Naha Desain Go Bad pikeun Programer Smart

Dina sababaraha bulan kapengker kuring parantos nganggo Go pikeun palaksanaan. Bukti Konsep (kira-kira.: kode pikeun nguji fungsionalitas hiji gagasan) dina waktu luang-Na, sabagean keur diajar basa programming sorangan. Program sorangan saderhana pisan sareng sanés tujuan tulisan ieu, tapi pangalaman ngagunakeun Go sorangan pantes sababaraha kecap ngeunaan éta. Go janji bakal jadi (kira-kira.: artikel ditulis dina 2015) basa populér pikeun kode scalable serius. Basa ieu dijieun ku Google, dimana eta aktip dipake. Bottom line, kuring jujur ​​nyangka yén desain basa Go goréng pikeun programer pinter.

Dirancang pikeun programer lemah?

Go pisan gampang pikeun neuleuman, jadi gampang éta bubuka nyandak kuring hiji sore, sanggeus éta kuring geus bisa kode productively. Buku anu kuring biasa diajar Go disebut Hiji Perkenalan pikeun Programming di Go (tarjamahan), éta sayogi online. Buku, sapertos kode sumber Go sorangan, gampang dibaca, gaduh conto kode anu saé, sareng ngandung sakitar 150 halaman anu tiasa dibaca sakaligus. Kesederhanaan ieu mimiti nyegerkeun, khususna dina dunya pemrograman anu pinuh ku téknologi anu langkung rumit. Tapi tungtungna, engké atanapi engké timbul pamikiran: "Naha ieu leres?"

Google nyatakeun kesederhanaan Go mangrupikeun titik jual sareng basana dirancang pikeun produktivitas maksimal dina tim ageung, tapi kuring ragu. Aya fitur anu leungit atanapi langkung rinci. Sareng sadaya kusabab kurangna kapercayaan dina pamekar, kalayan anggapan yén aranjeunna henteu tiasa ngalakukeun anu leres. Kahayang pikeun kesederhanaan ieu mangrupikeun kaputusan sadar ku désainer basa, sareng pikeun ngartos sapinuhna naha éta diperyogikeun, urang kedah ngartos motivasi para pamekar sareng naon anu aranjeunna cobian ngahontal di Go.

Ku kituna naha ieu dijieun jadi basajan? Ieu sababaraha tanda petik Rob Pike (kira-kira.: salah sahiji co-pencipta basa Go):

Titik konci di dieu nyaéta yén programer kami (kira-kira.: Googlers) lain panalungtik. Aranjeunna, sakumaha aturan, rada ngora, datang ka kami sanggeus diajar, sugan maranéhna diajar Java, atawa C / C ++, atawa Python. Aranjeunna henteu tiasa ngartos basa anu saé, tapi dina waktos anu sami kami hoyong aranjeunna nyiptakeun parangkat lunak anu saé. Éta sababna basana kedah gampang kaharti sareng diajar.
 
Anjeunna kedah wawuh, kasarna nyarios sami sareng C. Programer anu damel di Google ngamimitian karirna awal sareng biasana akrab sareng basa prosedural, khususna kulawarga C. Sarat pikeun produktivitas gancang dina basa pamrograman énggal hartosna yén basa éta henteu kedah radikal teuing.

Naon? Janten Rob Pike dasarna nyarios yén pamekar di Google henteu saé, éta sababna aranjeunna nyiptakeun basa pikeun jalma bodo (kira-kira.: dumbed handap) ambéh maranéhanana bisa ngalakukeun hiji hal. Naon jenis katingal sombong di kolega Anjeun sorangan? Kuring sok percaya yén pamekar Google dipilih ti anu paling terang sareng pangsaéna di Bumi. Pasti aranjeunna tiasa ngadamel anu langkung hese?

Artefak tina kesederhanaan kaleuleuwihan

Sederhana mangrupikeun tujuan anu pantes dina desain naon waé, sareng nyobian ngadamel anu saderhana sesah. Nanging, nalika nyobian ngabéréskeun (atanapi nganyatakeun) masalah anu rumit, kadang-kadang peryogi alat anu kompleks. Pajeulitna sareng intricacy sanes fitur pangsaéna tina basa pamrograman, tapi aya jalan tengah dimana basa tiasa nyiptakeun abstraksi anu elegan anu gampang kahartos sareng dianggo.

Teu pisan ekspresif

Kusabab komitmenna kana kesederhanaan, Go kakurangan konstruksi anu dianggap alami dina basa sanés. Ieu mungkin sigana kawas ide nu sae dina mimitina, tapi dina praktekna eta ngakibatkeun kode verbose. Alesan pikeun ieu kedah écés - éta kedah gampang pikeun pamekar maca kodeu jalma sanés, tapi kanyataanna nyederhanakeun ieu ngan ukur ngabahayakeun kabaca. Henteu aya singketan dina Go: boh seueur atanapi henteu.

Salaku conto, utilitas konsol anu maca stdin atanapi file tina argumen baris paréntah bakal katingali sapertos kieu:

package main

import (
    "bufio"
    "flag"
    "fmt"
    "log"
    "os"
)

func main() {

    flag.Parse()
    flags := flag.Args()

    var text string
    var scanner *bufio.Scanner
    var err error

    if len(flags) > 0 {

        file, err := os.Open(flags[0])

        if err != nil {
            log.Fatal(err)
        }

        scanner = bufio.NewScanner(file)

    } else {
        scanner = bufio.NewScanner(os.Stdin)
    }

    for scanner.Scan() {
        text += scanner.Text()
    }

    err = scanner.Err()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(text)
}

Sanaos kodeu ieu ogé nyobian janten umum sabisa-bisa, verbosity paksa Go ngahalangan, sareng salaku hasilna, ngarengsekeun masalah anu sederhana nyababkeun jumlah kode anu ageung.

Ieu, contona, mangrupikeun solusi pikeun masalah anu sami dina D:

import std.stdio, std.array, std.conv;

void main(string[] args)
{
    try
    {
        auto source = args.length > 1 ? File(args[1], "r") : stdin;
        auto text   = source.byLine.join.to!(string);

        writeln(text);
    }
    catch (Exception ex)
    {
        writeln(ex.msg);
    }
}

Sareng saha anu langkung tiasa dibaca ayeuna? Kuring bakal masihan sora kuring ka D. Kode na langkung gampang dibaca sabab anjeunna ngajelaskeun tindakan anu langkung jelas. D ngagunakeun konsep anu leuwih kompleks (kira-kira.: panggero fungsi alternatif и nyai) ti dina conto Go, tapi teu aya anu rumit pikeun ngartos aranjeunna.

Naraka niron

Saran populér pikeun ningkatkeun Go nyaéta umum. Ieu sahenteuna bakal ngabantosan nyegah nyalin kode anu teu perlu pikeun ngadukung sadaya jinis data. Salaku conto, fungsi pikeun nyimpulkeun daptar integer tiasa dilaksanakeun ku cara sanés ku cara nyalin-témpélkeun fungsi dasarna pikeun unggal jinis integer; teu aya deui cara sanés:

package main

import "fmt"

func int64Sum(list []int64) (uint64) {
    var result int64 = 0
    for x := 0; x < len(list); x++ {
        result += list[x]
    }
    return uint64(result)
}

func int32Sum(list []int32) (uint64) {
    var result int32 = 0
    for x := 0; x < len(list); x++ {
        result += list[x]
    }
    return uint64(result)
}

func int16Sum(list []int16) (uint64) {
    var result int16 = 0
    for x := 0; x < len(list); x++ {
        result += list[x]
    }
    return uint64(result)
}

func int8Sum(list []int8) (uint64) {
    var result int8 = 0
    for x := 0; x < len(list); x++ {
        result += list[x]
    }
    return uint64(result)
}

func main() {

    list8  := []int8 {1, 2, 3, 4, 5}
    list16 := []int16{1, 2, 3, 4, 5}
    list32 := []int32{1, 2, 3, 4, 5}
    list64 := []int64{1, 2, 3, 4, 5}

    fmt.Println(int8Sum(list8))
    fmt.Println(int16Sum(list16))
    fmt.Println(int32Sum(list32))
    fmt.Println(int64Sum(list64))
}

Sareng conto ieu henteu tiasa dianggo pikeun jinis anu ditandatanganan. Pendekatan ieu lengkep ngalanggar prinsip henteu ngulang deui diri anjeun (garing), salah sahiji prinsip nu kawentar tur atra, ignoring nu mangrupakeun sumber loba kasalahan. Naha Go ngalakukeun ieu? Ieu mangrupikeun aspék basa anu dahsyat.

Conto anu sami dina D:

import std.stdio;
import std.algorithm;

void main(string[] args)
{
    [1, 2, 3, 4, 5].reduce!((a, b) => a + b).writeln;
}

Sederhana, elegan sareng langsung ka titik. Fungsi anu dianggo di dieu nyaéta reduce pikeun tipe template jeung predikat. Leres, ieu deui langkung rumit tibatan versi Go, tapi henteu sesah pikeun programer pinter ngartos. Conto mana anu langkung gampang dijaga sareng langkung gampang dibaca?

Saderhana tipe sistem bypass

Kuring ngabayangkeun Go programer maca ieu bakal foaming dina sungut jeung screaming, "Anjeun nuju ngalakonan eta salah!" Nya, aya cara sanés pikeun ngadamel fungsi sareng jinis umum, tapi éta lengkep ngarecah sistem jinis!

Tingali kana conto ieu perbaikan basa bodo pikeun ngungkulan masalah:

package main

import "fmt"
import "reflect"

func Reduce(in interface{}, memo interface{}, fn func(interface{}, interface{}) interface{}) interface{} {
    val := reflect.ValueOf(in)

    for i := 0; i < val.Len(); i++ {
        memo = fn(val.Index(i).Interface(), memo)
    }

    return memo
}

func main() {

    list := []int{1, 2, 3, 4, 5}

    result := Reduce(list, 0, func(val interface{}, memo interface{}) interface{} {
        return memo.(int) + val.(int)
    })

    fmt.Println(result)
}

palaksanaan ieu Reduce injeuman tina artikel Idiomatic generics di Go (kira-kira.: Abdi henteu tiasa mendakan tarjamahan, kuring bakal bungah upami anjeun ngabantosan ieu). Muhun, upami éta idiomatic, Abdi hate ningali conto non-idiomatic. Pamakéan interface{} - a farce, sarta dina basa diperlukeun ukur keur bypass ketikan. Ieu mangrupikeun antarbeungeut kosong sareng sadaya jinis ngalaksanakeunana, ngamungkinkeun kabébasan lengkep pikeun sadayana. Gaya pemrograman ieu parah pisan, sareng sanés waé. Acrobatic feats kawas ieu merlukeun pamakéan pantulan runtime. Malah Rob Pike henteu resep jalma anu nyiksa ieu, sakumaha anu disebatkeun dina salah sahiji laporan na.

Ieu mangrupikeun alat anu kuat anu kedah dianggo kalayan ati-ati. Ieu kudu dihindari iwal mun mastikeun diperlukeun.

Abdi nyandak témplat D tinimbang omong kosong ieu. Kumaha saha tiasa nyarios kitu interface{} leuwih dibaca atawa malah ngetik aman?

The Woes of Manajemén kagumantungan

Go ngagaduhan sistem kagumantungan anu diwangun dina luhureun panyadia hosting populér VCS. Parabot anu aya sareng Go terang ngeunaan jasa ieu sareng tiasa ngaunduh, ngawangun, sareng masang kode ti aranjeunna dina hiji waktos. Bari ieu hébat, aya cacad utama kalawan versioning! Leres, leres yén anjeun tiasa nampi kode sumber tina jasa sapertos github atanapi bitbucket nganggo alat Go, tapi anjeun henteu tiasa netepkeun versina. Jeung deui kesederhanaan di expense of usefulness. Abdi henteu tiasa ngartos logika kaputusan sapertos kitu.

Saatos naroskeun patarosan ngeunaan solusi pikeun masalah ieu, tim pangembangan Go nyiptakeun thread forum, nu outlined kumaha aranjeunna bade meunang sabudeureun masalah ieu. Rekomendasi maranéhanana nyaéta ngan saukur nyalin sakabéh Repository kana proyék anjeun hiji poé sarta ninggalkeun eta "sakumaha aya". Naon sih anu aranjeunna pikir? Kami ngagaduhan sistem kontrol vérsi anu luar biasa kalayan tag anu saé sareng dukungan vérsi anu teu dipaliré ku panyipta Go sareng ngan ukur nyalin kodeu sumber.

Bagasi budaya ti Xi

Dina pamanggih kuring, Go dikembangkeun ku jalma anu parantos nganggo C sapanjang hirupna sareng ku anu henteu hoyong nyobian anu énggal. Basana tiasa didadarkeun salaku C kalayan roda tambahan (orig.: roda latihan). Teu aya ideu anyar di jerona, iwal pikeun ngadukung paralelisme (anu, ku jalan, éndah) sareng ieu éra. Anjeun gaduh paralelisme anu saé dina basa anu teu tiasa dianggo, pincang.

Masalah creaking séjén nyaéta yén Go nyaéta basa prosedural (sapertos horor jempé tina C). Anjeun mungkas nepi nulis kode dina gaya prosedural nu karasaeun kolot jeung tinggaleun jaman. Kuring terang program berorientasi obyék sanés pélor pérak, tapi langkung saé upami tiasa abstrak rinci kana jinis sareng nyayogikeun enkapsulasi.

Kesederhanaan pikeun kapentingan anjeun sorangan

Go dirancang pikeun saderhana sareng suksés dina tujuan éta. Ieu ditulis pikeun programer lemah, ngagunakeun basa heubeul salaku citakan. Datang kumplit jeung parabot basajan pikeun ngalakukeun hal basajan. Éta gampang dibaca sareng gampang dianggo.

Ieu pisan verbose, unimpressive, sarta goréng pikeun programer pinter.

Спасибо mersinvald pikeun éditan

sumber: www.habr.com

Tambahkeun komentar