github.com/nibnait/go-learn@v0.0.0-20220227013611-dfa47ea6d2da/chapter/README.md (about)

     1  [https://github.com/geektime-geekbang/go_learning](https://github.com/geektime-geekbang/go_learning)
     2  
     3  ## ch1 基本数据类型
     4  
     5  ### 数据类型 02_type_test.go
     6  
     7  #### 基本数据类型
     8  
     9  bool
    10  string
    11  int    int8    int16    int32    int64
    12  uint    uint8    uint16    uint32    uint64    uintptr
    13  byte    // alias for uint8
    14  rune    // alias for int32, represents a Unicode code point
    15  float32    float64
    16  complex64    complex128
    17  
    18  #### 类型转换
    19  
    20  go 语言 **不支持隐式**类型转换  
    21  显示类型转换,OK
    22  
    23  
    24  #### 类型的预定义值
    25  
    26  math.MaxInt64
    27  math.MaxFloat64
    28  math.MaxUint32
    29  
    30  
    31  ##### 与其他主要编程语言的差异
    32  
    33  1. 不支持指针运算
    34  2. string 是值类型,其默认的初始化值为空字符串,而不是 nil
    35  
    36  ### 运算符 04_operator_test.go
    37  
    38  #### 算术运算符
    39  
    40  ![](./img/算术运算符.png)
    41  
    42  #### 比较运算符
    43  
    44  ![](./img/比较运算符.png)
    45  
    46  #### 用 == 比较数组
    47  
    48  相同维数且含有相同个数元素的数组才可以比较
    49  每个元素都相同的才相等
    50  
    51  #### 逻辑运算符
    52  
    53  ![](./img/逻辑运算符.png)
    54  
    55  #### 位运算符
    56  
    57  ![](./img/位运算符.png)
    58  
    59  ##### 与其他主要编程语言的差异
    60  
    61  ![](./img/按位置零.png)
    62  
    63  ### 循环 05_loop_test.go
    64  
    65  一个 for
    66  
    67  ### 条件 06_condition_test.go
    68  
    69  #### if 条件
    70  
    71  ##### 与其他主要编程语言的差异
    72  
    73  1. condition 表达式结果必须为布尔值
    74  2. 支持变量赋值:
    75  
    76  ```go
    77  if var declaration; condition {
    78    // code to be executed if condition is true
    79  }
    80  ```
    81  
    82  #### switch 条件
    83  
    84  ##### 与其他主要编程语言的差异
    85  
    86  1. 条件表达式不限制为常量或者整数;
    87  2. 单个 case 中,可以出现多个结果选项,使用逗号分隔;(TestSwitchMultiCase)
    88     3.与C/Java语言等规则相反,Go语言不需要用break来明确退出一个case;
    89     4.可以不设定switch之后的条件表达式,在此种情况下,整个switch结构与多个 if...else... 的逻辑作用等同(TestSwitchCaseCondition)
    90  
    91  
    92  ### 数组 07_array_test.go
    93  
    94  #### 数组截取
    95  
    96  ```go
    97  // a[开始索引(包含), 结束索引(不包含)]
    98  func TestArraySection(t *testing.T) {
    99  	arr := [...]int{0, 1, 2, 3, 4, 5}
   100  	assert.Equal(t, arr[1:2], [...]int{1})
   101  	assert.Equal(t, arr[1:3], [...]int{1, 2})
   102  	assert.Equal(t, arr[1:], [...]int{1, 2, 3, 4, 5})
   103  	assert.Equal(t, arr[:3], [...]int{0, 1, 2})
   104  }
   105  ```
   106  
   107  ### 切片 08_slice_test.go
   108  
   109  ![](./img/slice_growing_test.png)
   110  
   111  ###  Map 09_map_test.go
   112  
   113  ```go
   114  func TestAccessNotExistingKey(t *testing.T) {
   115  	if value, isExist := m1[3]; isExist {
   116  		t.Logf("key 3 存在。 value = %d", value)
   117  	} else {
   118  		t.Log("key 3 不存在")
   119  	}
   120  }
   121  
   122  func TestTravelMap(t *testing.T) {
   123  	m1 := map[int]int{1: 1, 2: 4, 3: 9}
   124  
   125  	for k, v := range m1 {
   126  		t.Log(k, v)
   127  	}
   128  
   129  }
   130  ```
   131  
   132  #### 10_mal_ext_test.go
   133  
   134  ```go
   135  map[key]func(){}
   136  map[key]bool{}
   137  ```
   138  
   139  ### 字符串 11_string_fun_test.go
   140  
   141  #### 与其他主要变成语言的差异
   142  
   143  1. string 是数据类型,不是引用或指针类型
   144  2. string 是只读的 byte slice,len 函数可以它所包含的 byte 数
   145  3. string 的 byte 数组可以存放任何数据
   146  
   147  1.strings包  [https://golang.org/pkg/strings/](https://golang.org/pkg/strings/)
   148  2.strconv包 [https://golang.org/pkg/strconv/](https://golang.org/pkg/strconv/)
   149  
   150  # ch2 函数及面向对象介绍
   151  
   152  ### Go 语言的函数
   153  
   154  #### 与其他主要变成语言的差异(Go语言的函数是一等公民)
   155  
   156  1. 可以有多个返回值
   157  2. 所有参数都是**值传递**:slice, map, channel 会有传引用的错觉
   158  3. 函数可以作为变量的值
   159  4. 函数可以作为参数和返回值
   160  
   161  ---
   162  
   163  ### Go 语言 是面向对象的语言吗?
   164  
   165  yes and no. [https://go.dev/doc/faq#Is_Go_an_object-oriented_language](https://go.dev/doc/faq#Is_Go_an_object-oriented_language)
   166  ​
   167  
   168  ### 封装
   169  
   170  ```go
   171  type Person struct {
   172      name string
   173      age int
   174  }
   175  ```
   176  
   177  ### 接口
   178  
   179  _与其他主要变成语言的差异(Go语言的函数是一等公民):_
   180  1.接口为非入侵性,实现不依赖于借口定义
   181  2.所以接口的定义可以包含在接口使用者包内
   182  
   183  ### 扩展与复用(继承)
   184  
   185  17_extension_test.go
   186  _与其他主要变成语言的差异:_
   187  **不支持**继承、**不支持**重载、**不支持**LSP
   188  它不是继承,如果我们把“内部 struct ”看作⽗类,把“外部 struct” 看作⼦类, 会发现如下问题:
   189  
   190  1. 不⽀持⼦类替换
   191  2. ⼦类并不是真正继承了⽗类的⽅法
   192     • ⽗类的定义的⽅法⽆法访问⼦类的数据和⽅法
   193  
   194  ### 多态
   195  
   196  18_polymorphism_test.go
   197  1个接口,多个实现
   198  
   199  ### 空接口与断言
   200  
   201  19_empty_interface_test.go
   202  
   203  1. 空接⼝可以表示任何类型
   204  2. 通过断⾔来将空接⼝转换为制定类型
   205  
   206  ```go
   207  v, ok := p.(int) //ok=true 时为转换成功
   208  ```
   209  
   210  # ch3 项目编程规范
   211  
   212  ### Go 的错误机制
   213  
   214  20_err_test.go
   215  
   216  #### 与其他主要变成语言的差异
   217  
   218  1. 没有异常 try catch 机制
   219  2. error 类型实现了 error 接⼝
   220  
   221  ```go
   222  type error interface { 
   223      Error() string 
   224  } 
   225  ```
   226  
   227  3. 可以通过 errors.New 来快速创建错误实例
   228  
   229  ```go
   230  errors.New("n must be in the range [0,100]")
   231  ```
   232  
   233  #### panic vs os.Exit
   234  
   235  21_panic_recover_test.go
   236  
   237  | panic                               | os.Exit                                 |
   238  | ----------------------------------- | --------------------------------------- |
   239  | panic ⽤于不可以恢复的错误          |                                         |
   240  | panic 退出前会执⾏ defer 指定的内容 | os.Exit 退出时不会调⽤ defer 指定的函数 |
   241  | os.Exit 退出时不输出当前调⽤栈信息  |                                         |
   242  
   243  ## 包 package
   244  
   245  
   246  1. 基本复⽤模块单元 以⾸字⺟⼤写来表明可被包外代码访问
   247  2. 代码的 package 可以和所在的⽬录不⼀致
   248  3. 同⼀⽬录⾥的 Go 代码的 package 要保持⼀致
   249  
   250  ### init 方法
   251  
   252  - 在 main 被执⾏前,所有依赖的 package 的 init ⽅法都会被执⾏
   253  - 不同包的 init 函数按照包导⼊的依赖关系决定执⾏顺序
   254  - 每个包可以有多个 init 函数
   255  - 包的每个源⽂件也可以有多个 init 函数,这点⽐较特殊
   256  
   257  ### 获取远程依赖
   258  
   259  1. 通过 go get 来获取远程依赖
   260  
   261     go get -u "github.com/easierway/concurrent_map"
   262  
   263  
   264  2. 注意代码在 GitHub 上的组织形式,以适应 go get
   265  
   266     直接以代码路径开始,不要有 src
   267  
   268     示例: https://github.com/easierway/concurrent_map
   269  
   270  ---
   271  
   272  常用 module
   273  
   274  > go get -u github.com/easierway/concurrent_map
   275  >
   276  > go get -u github.com/stretchr/testify/assert
   277  >
   278  > go get -u github.com/smartystreets/goconvey/convey
   279  >
   280  > go get -u github.com/mailru/easyjson/...
   281  >
   282  > go get -u github.com/julienschmidt/httprouter