Goが適切に設計されていないプログラミング言語である理由

これは、reddit.com / r / programmingで広範な議論を受けているMediumのtucnakユーザー名の記事の翻訳です



画像

さて、見出しは本当に少し騒々しいです、私は認めます。 私はもっ​​と言います:注目を集めているからです。 このブログ投稿では、Goが非常に考え抜かれた言語であるという事実を証明しようとします(ネタバレ:そうです)。 私はすでに数か月間Goで遊んでいますが、最初のhelloworldは6月にまとめられたようです。 私は数学者ではありませんが、それから約4か月が経ち、 Githubにいくつかのリポジトリをアップロードして星を集めることさえできました! また、本番環境でGoを使用した経験はまったくないので、「コードサポート」または「デプロイ」についての私の言葉は、唯一の真実ではありません。



私はGoが大好きで、初めて試したときはとても気に入りました。 私はイディオムを受け入れ、ジェネリックの欠如に和解し、エラーを処理する率直に奇妙な方法を整理し、Goに何らかの形で関連するこれらの古典的な問題をすべて整理しました。 Effective Goを読んで Dave Cheney ブログの多くの記事を読んで、Goの世界のすべてのニュースをフォローしました。 私はコミュニティにかなり積極的に参加しているとさえ言えます! 私は囲loveが大好きで、それについて何もできません-囲Goは素晴らしいです。 ただし、Goはひどくよく考えられていない言語であり、「販売」するものではありません。



Goは単純なプログラミング言語と見なされます。 Rob Pikeが言ったように 、彼らは言語から「削除できるものをすべて削除した」ので、その仕様は簡単になりました。 言語のこちら側は単純です。基本を数分で習得し、すぐに実際のコードの記述を開始できます。ほとんどの場合、Goは期待どおりに動作します。 あなたは大いに怒りますが、幸いなことに、すべてがクールに動作します。 現実には、すべてが少し異なります; Goは単純な言語ではなく、単なる悪い言語です。 次に、私の言葉を裏付けるいくつかの議論を見てください。



理由#1。 スライスの操作は嫌です


スライス (これらは非常に洗練された配列です)は非常にクールで、コンセプトと実装自体が本当に好きです。 しかし、ある時点で、おそらく少しだけソースコードを書きたいと思います。 スライスは言語の中心であり、これはGoをクールにする概念の1つです。 しかし、それでも、「コンセプト」に関する会話の合間に、どういうわけか、突然、実際のコードを少し書きたいと思います。 この場合にGoが提供するものは次のとおりです。



//    ...
numbers := []int{1, 2, 3, 4, 5}

log(numbers)         // 1. [1 2 3 4 5]
log(numbers[2:])     // 2. [3 4 5]
log(numbers[1:3])    // 3. [2 3]

//  :    !
//
// numbers[:-1]  Python  .   
//  -      :
//
log(numbers[:len(numbers)-1])    // 4. [1 2 3 4]

// “” ,  ! !
//
//     :
//
numbers = append(numbers, 6)

log(numbers) // 5. [1 2 3 4 5 6]

//      :
//
numbers = append(numbers[:2], numbers[3:]...)

log(numbers)    // 6. [1 2 4 5 6]

//   - ?  ,
//  Go   best practice!
//
//        ...
//
numbers = append(numbers[:2], append([]int{3}, numbers[2:]...)...)

log(numbers)    // 7. [1 2 3 4 5 6]

//   ,     :
//
copiedNumbers := make([]int, len(numbers))
copy(copiedNumbers, numbers)

log(copiedNumbers)    // 8. [1 2 3 4 5 6]

//     .

      
      





, — , . , insert(), . a playground, : .



№2. :)


, « Go , » , . , spf13 Docker «7 common mistakes in Go and when to avoid them».

, error (, , ). , . , , , ?



package main

import "fmt"

type MagicError struct{}

func (MagicError) Error() string {
	return "[Magic]"
}

func Generate() *MagicError {
	return nil
}

func Test() error {
	return Generate()
}

func main() {
	if Test() != nil {
		fmt.Println("Hello, Mr. Pike!")
	}
}

      
      





, , , Go. , . . , Go , , - ;)



№3.


, , - : “ , ( , , ) , ”. , , . , Go , : :=, . Go:



package main

import "fmt"

func Secret() (int, error) {
	return 42, nil
}

func main() {
	number := 0

	fmt.Println("before", number) // 0

	{
		// meet the shadowing
		number, err := Secret()
		if err != nil {
			panic(err)
		}

		fmt.Println("inside", number) // 42
	}

	fmt.Println("after", number) // 0
}

      
      





, , := , . . , ( ) , («after 42»). , ? .

, , , , . Go . , , , .



№4. []struct []interface


, Pike&Co. , , Go: , , Go . , «Effective Go» . , « », , , , Go . , ( ) , :



package main

import (
	"fmt"
	"strconv"
)

type FancyInt int

func (x FancyInt) String() string {
	return strconv.Itoa(int(x))
}

type FancyRune rune

func (x FancyRune) String() string {
	return string(x)
}

//      String().
type Stringy interface {
	String() string
}

// ,      .
func Join(items []Stringy) (joined string) {
	for _, item := range items {
		joined += item.String()
	}

	return
}

func main() {
	numbers := []FancyInt{1, 2, 3, 4, 5}
	runes := []FancyRune{'a', 'b', 'c'}

	//   !
	//
	// fmt.Println(Join(numbers))
	// fmt.Println(Join(runes))
	//
	// prog.go:40: cannot use numbers (type []FancyInt) as type []Stringy in argument to Join
	// prog.go:41: cannot use runes (type []FancyRune) as type []Stringy in argument to Join
	//
	//        :
	//

	properNumbers := make([]Stringy, len(numbers))
	for i, number := range numbers {
		properNumbers[i] = number
	}

	properRunes := make([]Stringy, len(runes))
	for i, r := range runes {
		properRunes[i] = r
	}

	fmt.Println(Join(properNumbers))
	fmt.Println(Join(properRunes))
}

      
      





, , - . Go, ? Wiki , , []struct []interface . , ! , , . , , . Go ? -, , ?



, , « , ». . , Go .



№5. « »


UPD: , . , , .. , .



, - Go. , «for-range» , . . , , : range- « », —  foreach ++.



package main

import "fmt"

func main() {
	numbers := []int{0, 1, 2, 3, 4}

	for _, number := range numbers {
		number++
	}

	fmt.Println(numbers) // [0 1 2 3 4]

	for i, _ := range numbers {
		numbers[i]++
	}

	fmt.Println(numbers) // [1 2 3 4 5]
}

      
      





, , Go range- « », , range- . “range” “ ”, “ ”. For “Effective Go”, , range- , . , , ( ), , , . , “Effective Go”.



№6.


, Go , . , unused import. ? , . , , unused import , . , - , , - ? , ?



Go1.5 : - . Go team , , .



, Go — . , Go (import / var / const):

import (
    "fmt"
    "math"
    "github.com/some_guy/fancy"
)
const (
    One int = iota
    Two
    Three
)
var (
    VarName int = 35
)

      
      





, «», , . - , , . , , :

numbers := []Object{
    Object{"bla bla", 42}
    Object("hahauha", 69}
}

      
      





:

numbers := []Object{
    Object{"bla bla", 42},
    Object("hahauha", 69},
}

      
      





, import / var / const . , , . !



№7. Go


-, . , Go, , , . , go:generate — Go, , . , , , . , . , , - , . , - ! , :



func Blabla() {
    // code...
}

//go:generate toolname -params -blabla

// code...

      
      





, . , Go. , , , . , , unused imports, .





, / / , Go. , , , , . , , ! « » , , , « » .



, Go. : . : , , , , .



, , Go?



All Articles