Skip to content

Commit 2fbe185

Browse files
committed
feat: update articles
1 parent 66d0e2f commit 2fbe185

10 files changed

Lines changed: 470 additions & 79 deletions

File tree

‎Go/变量操作/变量与常量.md‎

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ var variableName type = value
1919
*/
2020
var vname1, vname2, vname3 type= v1, v2, v3
2121

22+
// 定义多个变量
23+
var (
24+
home = os.Getenv("HOME")
25+
user = os.Getenv("USER")
26+
gopath = os.Getenv("GOPATH")
27+
)
28+
2229
/*
2330
 定义三个变量,它们分别初始化为相应的值 vname1 为 v1,vname2 为 v2,vname3 为 v3 编译器会根据初始化的值自动推导出相应的类型
2431
*/
@@ -43,7 +50,9 @@ func main() {
4350

4451
# 常量
4552

46-
所谓常量,也就是在程序编译阶段就确定下来的值,而程序在运行时无法改变该值。在 Go 程序中,常量可定义为数值、布尔值或字符串等类型。它的语法如下:
53+
所谓常量,也就是在程序编译阶段就确定下来的值,而程序在运行时无法改变该值,Go 中的常量就是不变量。它们在编译时创建,即便它们可能是函数中定义的局部变量。常量只能是数字、字符(符文)、字符串或布尔值。由于编译时的限制, 定义它们的表达式必须也是可被编译器求值的常量表达式。例如 `1<<3` 就是一个常量表达式,而 `math.Sin(math.Pi/4)` 则不是,因为对 `math.Sin` 的函数调用在运行时才会发生。
54+
55+
它的语法如下:
4756

4857
```go
4958
const constantName = value
@@ -61,3 +70,45 @@ const prefix = "astaxie_"
6170
```
6271

6372
Go 常量和一般程序语言不同的是,可以指定相当多的小数位数(例如 200 位),若指定給 float32 自动缩短为 32bit,指定给 float64 自动缩短为 64bit,详情参考[链接](http://golang.org/ref/spec#Constants)
73+
74+
## iota
75+
76+
在 Go 中,枚举常量使用枚举器 iota 创建。由于 iota 可为表达式的一部分,而表达式可以被隐式地重复,这样也就更容易构建复杂的值的集合了。每次 const 出现时,都会让 iota 初始化为 0。
77+
78+
```go
79+
const a = iota // a=0
80+
const (
81+
b = iota //b=0
82+
c //c=1
83+
)
84+
```
85+
86+
自增长常量经常包含一个自定义枚举类型,允许你依靠编译器完成自增设置。
87+
88+
```go
89+
type Stereotype int
90+
91+
const (
92+
TypicalNoob Stereotype = iota // 0
93+
TypicalHipster // 1
94+
TypicalUnixWizard // 2
95+
TypicalStartupFounder // 3
96+
)
97+
```
98+
99+
```go
100+
type ByteSize float64
101+
102+
const (
103+
// 通过赋予空白标识符来忽略第一个值
104+
_ = iota // ignore first value by assigning to blank identifier
105+
KB ByteSize = 1 << (10 * iota)
106+
MB
107+
GB
108+
TB
109+
PB
110+
EB
111+
ZB
112+
YB
113+
)
114+
```

‎Go/并发编程/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# 并发编程
22

3-
关于并发编程的通用基础内容,参阅
3+
关于并发编程的通用基础内容,参阅[并发编程导论 https://url.wx-coder.cn/Yagu8 ](https://url.wx-coder.cn/Yagu8)。
Lines changed: 10 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
# 基本类型
22

3-
## 数值类型
3+
# 数值类型
44

55
整数类型有无符号和带符号两种。Go 同时支持`int`和`uint`,这两种类型的长度相同,但具体长度取决于不同编译器的实现。Go 里面也有直接定义好位数的类型:`rune`, `int8`, `int16`, `int32`, `int64`和`byte`, `uint8`, `uint16`, `uint32`, `uint64`。其中`rune`是`int32`的别称,`byte`是`uint8`的别称。
66

7-
> 需要注意的一点是,这些类型的变量之间不允许互相赋值或操作,不然会在编译时引起编译器报错。
8-
>
9-
> 如下的代码会产生错误:invalid operation: a + b (mismatched types int8 and int32)
10-
>
11-
> > var a int8
12-
> >
13-
> > var b int32
14-
> >
15-
> > c:=a + b
16-
>
17-
> 另外,尽管 int 的长度是 32 bit, 但 int 与 int32 并不可以互用。
7+
需要注意的一点是,这些类型的变量之间不允许互相赋值或操作,不然会在编译时引起编译器报错。如下的代码会产生错误:`invalid operation: a + b (mismatched types int8 and int32)`
188

19-
浮点数的类型有`float32`和`float64`两种(没有`float`类型),默认是`float64`。
9+
```go
10+
var a int8
11+
var b int32
12+
c:=a + b
13+
```
14+
15+
另外,尽管 int 的长度是 32 bit, 但 int 与 int32 并不可以互用。浮点数的类型有`float32`和`float64`两种(没有`float`类型),默认是`float64`。
2016

2117
这就是全部吗?No!Go 还支持复数。它的默认类型是`complex128`(64 位实数+64 位虚数)。如果需要小一些的,也有`complex64`(32 位实数+32 位虚数)。复数的形式为`RE + IMi`,其中`RE`是实数部分,`IM`是虚数部分,而最后的`i`是虚数单位。下面是一个使用复数的例子:
2218

@@ -26,7 +22,7 @@ var c complex64 = 5+5i
2622
fmt.Printf("Value is: %v", c)
2723
```
2824

29-
## 布尔类型
25+
# 布尔类型
3026

3127
在 Go 中,布尔值的类型为`bool`,值是`true`或`false`,默认为`false`。
3228

@@ -40,66 +36,3 @@ func test() {
4036
    available = true    // 赋值操作
4137
}
4238
```
43-
44-
# String
45-
46-
我们在上一节中讲过,Go 中的字符串都是采用`UTF-8`字符集编码。字符串是用一对双引号(`""`)或反引号(`` ` `` `)括起来定义,它的类型是`string`。
47-
48-
```
49-
//示例代码
50-
var frenchHello string  // 声明变量为字符串的一般方法
51-
var emptyString string = ""  // 声明了一个字符串变量,初始化为空字符串
52-
func test() {
53-
    no, yes, maybe := "no", "yes", "maybe"  // 简短声明,同时声明多个变量
54-
    japaneseHello := "Konichiwa"  // 同上
55-
    frenchHello = "Bonjour"  // 常规赋值
56-
}
57-
```
58-
59-
在 Go 中字符串是不可变的,例如下面的代码编译时会报错:cannot assign to s[0]
60-
61-
```
62-
var s string = "hello"
63-
s[0] = 'c'
64-
```
65-
66-
但如果真的想要修改怎么办呢?下面的代码可以实现:
67-
68-
```
69-
s := "hello"
70-
c := []byte(s)  // 将字符串 s 转换为 []byte 类型
71-
c[0] = 'c'
72-
s2 := string(c)  // 再转换回 string 类型
73-
fmt.Printf("%s\n", s2)
74-
```
75-
76-
Go 中可以使用`+`操作符来连接两个字符串:
77-
78-
```
79-
s := "hello,"
80-
m := " world"
81-
a := s + m
82-
fmt.Printf("%s\n", a)
83-
```
84-
85-
修改字符串也可写为:
86-
87-
```go
88-
s := "hello"
89-
s = "c" + s[1:] // 字符串虽不能更改,但可进行切片操作
90-
fmt.Printf("%s\n", s)
91-
```
92-
93-
如果要声明一个多行的字符串怎么办?可以通过`` `来声明:
94-
95-
```
96-
m := `hello
97-
    world`
98-
```
99-
100-
`` ` 括起的字符串为 Raw 字符串,即字符串在代码中的形式就是打印时的形式,它没有字符转义,换行也将原样输出。例如本例中会输出:
101-
102-
```
103-
hello
104-
    world
105-
```

‎Go/数据结构/字符串.md‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# 字符串
2+
3+
我们在上一节中讲过,Go 中的字符串都是采用`UTF-8`字符集编码。字符串是用一对双引号(`""`)或反引号(`` ` `` `)括起来定义,它的类型是`string`。
4+
5+
```go
6+
//示例代码
7+
var frenchHello string  // 声明变量为字符串的一般方法
8+
var emptyString string = ""  // 声明了一个字符串变量,初始化为空字符串
9+
func test() {
10+
    no, yes, maybe := "no", "yes", "maybe"  // 简短声明,同时声明多个变量
11+
    japaneseHello := "Konichiwa"  // 同上
12+
    frenchHello = "Bonjour"  // 常规赋值
13+
}
14+
```
15+
16+
在 Go 中字符串是不可变的,例如下面的代码编译时会报错:cannot assign to s[0]
17+
18+
```
19+
var s string = "hello"
20+
s[0] = 'c'
21+
```
22+
23+
但如果真的想要修改怎么办呢?下面的代码可以实现:
24+
25+
```
26+
s := "hello"
27+
c := []byte(s)  // 将字符串 s 转换为 []byte 类型
28+
c[0] = 'c'
29+
s2 := string(c)  // 再转换回 string 类型
30+
fmt.Printf("%s\n", s2)
31+
```
32+
33+
Go 中可以使用`+`操作符来连接两个字符串:
34+
35+
```go
36+
s := "hello,"
37+
m := " world"
38+
a := s + m
39+
fmt.Printf("%s\n", a)
40+
```
41+
42+
修改字符串也可写为:
43+
44+
```go
45+
s := "hello"
46+
s = "c" + s[1:] // 字符串虽不能更改,但可进行切片操作
47+
fmt.Printf("%s\n", s)
48+
```
49+
50+
如果要声明一个多行的字符串怎么办?可以通过`` `来声明:
51+
52+
```go
53+
m := `hello
54+
    world`
55+
```
56+
57+
`` ` 括起的字符串为 Raw 字符串,即字符串在代码中的形式就是打印时的形式,它没有字符转义,换行也将原样输出。例如本例中会输出:
58+
59+
```
60+
hello
61+
    world
62+
```

‎Go/数据结构/映射.md‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# 映射
2+
3+
映射是方便而强大的内建数据结构,它可以关联不同类型的值。其键可以是任何相等性操作符支持的类型,如整数、浮点数、复数、字符串、指针、接口(只要其动态类型支持相等性判断)、结构以及数组。
4+
5+
切片不能用作映射键,因为它们的相等性还未定义。与切片一样,映射也是引用类型。若将映射传入函数中,并更改了该映射的内容,则此修改对调用者同样可见。
6+
7+
map 的零值为 nil。对于 map 的零值得读取,不会出错,但是写入则会引发 panic,例如:
8+
9+
```go
10+
func main() {
11+
var m map[string]string
12+
fmt.Println(m["hello"])
13+
m["hello"] = "world"
14+
}
15+
16+
// error
17+
panic: assignment to entry in nil map
18+
19+
goroutine 1 [running]:
20+
main.main()
21+
/tmp/main.go:10 +0xee
22+
exit status 2
23+
```
24+
25+
# 取值与遍历
26+
27+
对 map 取值,返回两个参数,第二个参数为 bool 值,标志 key 是否存在于 map 中:
28+
29+
```go
30+
s := m["hello"] // 如果key不存在,s为对应类型的零值
31+
s, ok := m["hello"] // 如果key不存在, ok为false,反之为true
32+
_, exists := m["hello"] // 用来确定key是否存在
33+
```

‎Go/模块机制/包.md‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,49 @@
11
# Package | 包
2+
3+
# init 函数
4+
5+
每个源文件都可以通过定义自己的无参数 init 函数来设置一些必要的状态;每个文件都可以拥有多个 init 函数。只有该包中的所有变量声明都通过它们的初始化器求值后 init 才会被调用, 而那些 init 只有在所有已导入的包都被初始化后才会被求值。除了那些不能被表示成声明的初始化外,init 函数还常被用在程序真正开始执行前,检验或校正程序的状态。
6+
7+
尽管 init 方法能够在同一个源文件中多次定义,并且顺序执行,应该尽量避免。同一个包下的多个源文件中的 init 执行顺序,依赖编译器 resolve 源代码文件的顺序,亦可以是手动指定文件的顺序,所以他们的执行顺序是不可靠的。所以一个包尽量一个 init 函数。
8+
9+
```go
10+
// main.go
11+
package main
12+
13+
import (
14+
"fmt"
15+
)
16+
17+
func init() {
18+
fmt.Println("main")
19+
}
20+
21+
func main() {
22+
}
23+
24+
```
25+
26+
```go
27+
// b.go
28+
package main
29+
30+
import (
31+
"fmt"
32+
)
33+
34+
func init() {
35+
fmt.Println("b")
36+
}
37+
38+
```
39+
40+
```go
41+
$ go build -o main main.go b.go
42+
$ ./main
43+
main
44+
b
45+
$ go build -o main b.go main.go
46+
./main
47+
b
48+
main
49+
```

‎Go/结构体与接口/内嵌.md‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# 内嵌
2+
3+
Go 语言中并没有子类继承这样的概念,而是通过嵌入(Embedding)的方式来实现类或者接口的组合。
4+
5+
```go
6+
// ReadWriter 的实现需要同时满足 Reader 与 Writer
7+
type ReadWriter interface {
8+
Reader
9+
Writer
10+
}
11+
12+
// Server 暴露了所有 Logger 结构体的方法
13+
type Server struct {
14+
Host string
15+
Port int
16+
*log.Logger
17+
}
18+
19+
// 初始化方式并未受影响
20+
server := &Server{"localhost", 80, log.New(...)}
21+
22+
// 却可以直接调用内嵌结构体的方法,等价于 server.Logger.Log(...)
23+
server.Log(...)
24+
25+
// 内嵌结构体的名词即是类型名
26+
var logger *log.Logger = server.Logger
27+
```

0 commit comments

Comments
 (0)