围棋规则 斜着连成一条线_进入围棋世界的第一步
圍棋規則 斜著連成一條線
由于開發人員每年都要學習一種新的編程語言 ,我覺得現在是時候投入新的東西了,我決定使用Go 。
好消息是Go擁有很棒的文檔來幫助您入門。 更好的消息是Go擁有成熟的工具生態系統 ,包括對獲取依賴項,格式化和測試的支持。
還有一個支持Go的Eclipse插件 。 盡管它不像對Java的支持那樣完整(例如,很少有快速修復或重構),但是它比我嘗試過的其他語言要好得多。
學習任何東西的最好方法是邊做邊學 ,所以我從簡單的kata開始:開發集合類型。 Go的標準庫不提供set ,但這是重點。 我只想通過學習一些熟悉的東西來學習語言。
因此,讓我們開始第一個測試。 Go中的約定是,如果要測試foo.go ,則創建一個名稱為foo_test.go的文件。
package setimport ("testing" )func TestEmpty(t *testing.T) {empty := NewSet()if !empty.IsEmpty() {t.Errorf("Set without elements should be empty")} }(WordPress當前不支持Go語法高亮顯示,因此func關鍵字不會這樣顯示。)
關于這段代碼,有幾件事要注意:
- Go使用package語句支持包
- 語句以分號( ; )終止,但是您可以在行的末尾忽略它們,就像在Groovy中一樣
- 您可以使用import語句導入包。 testing包是標準庫的一部分
- 以小寫字母開頭的所有內容都是包的私有內容,以大寫字母開頭的所有內容都是公共的
- Go中的代碼進入函數內部,如func關鍵字所示
- 變量名稱寫在類型之前
- :=語法是聲明和初始化變量的簡寫; 去會找出正確的類型
- Go沒有構造函數 ,但是使用工廠函數來實現相同的功能
- if語句不需要在條件周圍加上括號,但是需要大括號
- testing包很小,并且沒有斷言。 雖然有提供這些功能的軟件包,但我決定在此處保持默認值
因此,讓我們通過測試:
package settype set struct { }func NewSet() *set {return new(set) }func (s *set) IsEmpty() bool {return true }關于Eclipse插件的最酷的事情是,只要保存文件,它就會自動運行測試,就像InfiniTest for Java一樣。 當您進行測試驅動開發時,這真的很好。
現在,這當然不是一個測試,因為它僅測試IsEmpty()硬幣的一側。 這就是讓我們偽造實現的原因。 因此,讓我們修復測試:
func TestEmpty(t *testing.T) {empty := NewSet()one := NewSet()one.Add("A")if !empty.IsEmpty() {t.Errorf("Set without elements should be empty")}if one.IsEmpty() {t.Errorf("Set with one element should not be empty")} }我們可以輕松通過:
type set struct {empty bool }func NewSet() *set {s := new(set)s.empty = truereturn s }func (s *set) IsEmpty() bool {return s.empty }func (s *set) Add(item string) {s.empty = false }請注意,我已經使用string類型作為Add()的參數。 我們顯然希望有更通用的東西,但是Go中沒有Object ,而Java中沒有。 稍后我將重新討論該決定。
下一個測試將驗證集合中的項目數:
func TestSize(t *testing.T) {empty := NewSet()one := NewSet()one.Add("A")if empty.Size() != 0 {t.Errorf("Set without elements should have size 0")}if one.Size() != 1 {t.Errorf("Set with one element should have size 1")} }我們通過將empty歸納為size來傳遞:
type set struct {size int }func NewSet() *set {s := new(set)s.size = 0return s }func (s *set) IsEmpty() bool {return s.Size() == 0 }func (s *set) Add(item string) {s.size++ }func (s *set) Size() int {return s.size }現在測試通過了,我們需要對其進行一些清理:
var empty *set var one *setfunc setUp() {empty = NewSet()one = NewSet()one.Add("A") }func TestEmpty(t *testing.T) {setUp()if !empty.IsEmpty() {t.Errorf("Set without elements should be empty")}if one.IsEmpty() {t.Errorf("Set with one element should not be empty")} }func TestSize(t *testing.T) {setUp()if empty.Size() != 0 {t.Errorf("Set without elements should have size 0")}if one.Size() != 1 {t.Errorf("Set with one element should have size 1")} }再次注意,與例如JUnit相比,缺少測試基礎結構支持。 我們必須手動調用setUp()函數。
使代碼的形狀更好,讓我們添加下一個測試:
func TestContains(t *testing.T) {setUp()if empty.Contains("A") {t.Errorf("Empty set should not contain element")}if !one.Contains("A") {t.Errorf("Set should contain added element")} }要進行此傳遞,我們必須將項目實際存儲在集合中,這需要使用數組和切片 :
type set struct {items []string }func NewSet() *set {s := new(set)s.items = make([]string, 0, 10)return s }func (s *set) Add(item string) {s.items = append(s.items, item) }func (s *set) Size() int {return len(s.items) }func (s *set) Contains(item string) bool {for _, value := range s.items {if (value == item) {return true}}return false }切片是一種方便的類似數組的數據結構,由真實的ray支持。 數組不能改變大小,但是可以大于它們返回的切片。 這樣可以保持將項目附加到切片的效率。
for循環是Go中唯一的循環構造,但是它比大多數其他語言的for強大得多。 它同時提供了索引和值,我們首先使用下劃線( _ )忽略了索引和值。 它使用range關鍵字遍歷切片中的所有項目。
因此,現在我們有了各種各樣的集合,但還沒有一套:
func TestIgnoresDuplicates(t *testing.T) {setUp()one.Add("A")if one.Size() != 1 {t.Errorf("Set should ignore adding an existing element")} }func (s *set) Add(item string) {if !s.Contains(item) {s.items = append(s.items, item)} }我們要做的只是使所有功能都可以移除:
func TestRemove(t *testing.T) {setUp()one.Remove("A")if one.Contains("A") {t.Errorf("Set still contains element after removing it")} }func (s *set) Remove(item string) {for index, value := range s.items {if value == item {s.items[index] = s.items[s.Size() - 1]s.items = s.items[0:s.Size() - 1]}} }在這里,我們看到了for循環的完整形式,包括索引和值。 此循環與Contains()循環非常相似,因此我們可以提取一種方法來消除重復:
func (s *set) Contains(item string) bool {return s.indexOf(item) >= 0 }func (s *set) indexOf(item string) int {for index, value := range s.items {if value == item {return index}}return -1 }func (s *set) Remove(item string) {index := s.indexOf(item)if index >= 0 {s.items[index] = s.items[s.Size()-1]s.items = s.items[0 : s.Size()-1]} }請注意indexOf()上的小寫起始字母,使其成為私有方法。 由于我們的集合是無序的,因此公開此功能沒有任何意義。
最后,我們需要對集合進行概括,以便它可以包含任何類型的項目:
func TestNonStrings(t *testing.T) {set := NewSet()set.Add(1)if !set.Contains(1) {t.Errorf("Set does not contain added integer")}set.Remove(1)if set.Contains(1) {t.Errorf("Set still contains removed integer")} }一些挖掘表明,我們可以使用一個空接口在Go中模仿Java的Object :
type set struct {items []interface{} }func NewSet() *set {s := new(set)s.items = make([]interface{}, 0, 10)return s }func (s *set) IsEmpty() bool {return s.Size() == 0 }func (s *set) Add(item interface{}) {if !s.Contains(item) {s.items = append(s.items, item)} }func (s *set) Size() int {return len(s.items) }func (s *set) Contains(item interface{}) bool {return s.indexOf(item) >= 0 }func (s *set) indexOf(item interface{}) int {for index, value := range s.items {if value == item {return index}}return -1 }func (s *set) Remove(item interface{}) {index := s.indexOf(item)if index >= 0 {s.items[index] = s.items[s.Size()-1]s.items = s.items[0 : s.Size()-1]} }總而言之,我發現在Go中工作非常愉快。 語言簡單但功能強大。 go fmt了有關代碼布局的討論,編譯器對if.括號的堅持也是if. Go真正閃耀的地方是并發編程,但這又是另一回事了。
你怎么看? 您喜歡這種經過修飾的小語言嗎? 你會用嗎? 請在評論中留言。
翻譯自: https://www.javacodegeeks.com/2016/02/first-steps-world-go.html
圍棋規則 斜著連成一條線
總結
以上是生活随笔為你收集整理的围棋规则 斜着连成一条线_进入围棋世界的第一步的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 盘古越狱工具在用户空间的行为
- 下一篇: 2000元以内最强NAS 群晖DS211