2019年6月27日木曜日

開発環境

Head First Go (Jay McGavren(著)、O'Reilly Media)のChapter 13(sharing work - Goroutines and Channels)の397ページ、Fixing our web page size program with channels(continued)と398ページ、Updating our channel to carry a structのforループとスライスのインデックスを取得する、あるいは長さの回数だけ何か処理するためのコードについて。

本著のコードの書き方がGoらしいのかどうかちょっと気になったり。

C言語だと配列の長さの取得方法がないから、以下のようなコードに。

#include <stdio.h>

int main() {
  int n = 5;
  char chars[] = {'a', 'b', 'c', 'd', 'e'};
  // インデックスを使う場合
  for (int i = 0; i < n; i++) {
    printf("%d\n", i);
  }
  // 添字を使わないけど配列の長さの分だけ何かをする場合
  for (int i = 0; i < n; i++) {
    printf("Hello, C array!\n");
  }
}

入出力結果(Bash、cmd.exe(コマンドプロンプト)、Terminal)

$ cc sample.c && ./a.out
0
1
2
3
4
Hello, C array!
Hello, C array!
Hello, C array!
Hello, C array!
Hello, C array!
$ 

本著のGoのコードはC言語と似た感じの書き方で、長さの取得についてはlen関数を使用。(インデックスを使用しない場合。)

コード

package main

import "fmt"

func main() {
 cs := []byte{'a', 'b', 'c', 'd', 'e'}
 for i := 0; i < len(cs); i++ {
  fmt.Println("Hello, Go slice!")
 }
}

入出力結果(Bash、cmd.exe(コマンドプロンプト)、Terminal)

$ go run sample.go
Hello, Go slice!
Hello, Go slice!
Hello, Go slice!
Hello, Go slice!
Hello, Go slice!
$ 

ただ、個人の好みとしては次のように書きたくなったり。

コード

package main

import "fmt"

func main() {
 cs := []byte{'a', 'b', 'c', 'd', 'e'}
 // インデックスを使用する場合
 for i, _ := range cs {
  fmt.Println(i)
 }
 // 添字を使わないけど配列の長さの分だけ何かをする場合
 for range cs {
  fmt.Println("Hello, Go slice")
 }
}

入出力結果(Bash、cmd.exe(コマンドプロンプト)、Terminal)

$ go run sample.go
0
1
2
3
4
Hello, Go slice
Hello, Go slice
Hello, Go slice
Hello, Go slice
Hello, Go slice
$ 

というのも、普段Pythonを使用することが多くて、Pythonでは以下のような書き方がPythonicな方法だから。

コード

Python 3

cs = ['a', 'b', 'c', 'd', 'e']

# Pythonらしくないインデックスを使用する場合
for i in range(len(cs)):
    print(i)
# Pythonらしくない添字を使わないけど配列の長さの分だけ何かをする場合
for _ in range(len(cs)):
    print('Hello, Python list!')
# インデックスを使用する場合
for i, _ in enumerate(cs):
    print(i)

# 添字を使わないけど配列の長さの分だけ何かをする場合
for _ in enumerate(cs):
    print('Hello, Python list!')

入出力結果(Bash、cmd.exe(コマンドプロンプト)、Terminal、Jupyter(IPython))

$ python3 sample.py
0
1
2
3
4
Hello, Python list!
Hello, Python list!
Hello, Python list!
Hello, Python list!
Hello, Python list!
0
1
2
3
4
Hello, Python list!
Hello, Python list!
Hello, Python list!
Hello, Python list!
Hello, Python list!
$ 

(PythonとGo、どちらにもrange関数があるからややこしいかも。Goのrange関数とちょっと違うけど、Pythonで似たような機能をもつのはenumerateクラス。)

Go言語についてrange関数はlen関数より負荷がかかったり、あるいはC言語っぽい書き方の方がGopherらしい書き方だったりするのかなぁ。今のところどちらか分からないけど、今後人が書いたGoのコードを沢山読んでいくうちに、どちらがGoらしい書き方なのが自然と身についていくことを期待。

0 コメント:

コメントを投稿