Administrator
Administrator
Published on 2024-09-30 / 4 Visits
0
0

笔记

笔记

字面量

整形字面量

为了便于阅读,允许使用下划线_​来进行数字划分,但是仅允许在前缀符号之后数字之间使用。

24 // 24
024 // 24
2_4 // 24
0_2_4 // 24
10_000 // 10k
100_000 // 100k
0O24 // 20
0b00 // 0
0x00 // 0
0x0_0 // 0

浮点数字面量

通过不同的前缀可以表达不同进制的浮点数

0.
72.40
072.40       // == 72.40
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5
1_5.         // == 15.0
0.15e+0_2    // == 15.0

0x1p-2       // == 0.25
0x2.p10      // == 2048.0
0x1.Fp+0     // == 1.9375
0X.8p-0      // == 0.5
0X_1FFFP-16  // == 0.1249847412109375
0x15e-2      // == 0x15e - 2 (integer subtraction)

#复数字面量">#复数字面量

0i
0123i         // == 123i
0o123i        // == 0o123 * 1i == 83i
0xabci        // == 0xabc * 1i == 2748i
0.i
2.71828i
1.e+0i
6.67428e-11i
1E6i
.25i
.12345E+5i
0x1p-2i       // == 0x1p-2 * 1i == 0.25i

#字符字面量">#字符字面量

字符字面量必须使用单引号括起来''​,Go中的字符完全兼容utf8​。

'a'
'ä'
'你'
'\t'
'\000'
'\007'
'\377'
'\x07'
'\xff'
'\u12e4'
'\U00101234'

#转义字符">#转义字符

Go中可用的转义字符

\a   U+0007 响铃符号(建议调高音量)
\b   U+0008 回退符号
\f   U+000C 换页符号
\n   U+000A 换行符号
\r   U+000D 回车符号
\t   U+0009 横向制表符号
\v   U+000B 纵向制表符号
\\   U+005C 反斜杠转义
\'   U+0027 单引号转义 (该转义仅在字符内有效)
\"   U+0022 双引号转义 (该转义仅在字符串内有效)

#字符串字面量">#字符串字面量

字符串字面量必须使用双引号""​括起来或者反引号(反引号字符串不允许转义)

`abc`                // "abc"
`\n
\n`                  // "\\n\n\\n"
"\n"
"\""                 // `"`
"Hello, world!\n"
"今天天气不错"
"日本語"
"\u65e5本\U00008a9e"
"\xff\u00FF"

格式化

Go中的格式化输出功能基本上由fmt.Printf​函数提供,如果你学过C系语言,一定会觉得很熟悉,下面是一个简单的例子。

func main() {
	fmt.Printf("hello world, %s!", "jack")
}

下面是Go目前所有的格式化动词。

0

格式化

描述

接收类型

1

%%

输出百分号%

任意

2

%s

输出string​/[] byte​值

string​,[] byte

3

%q

格式化字符串,输出的字符串两端有双引号""

string​,[] byte

4

%d

输出十进制整型值

整型

5

%f

输出浮点数

浮点

6

%e

输出科学计数法形式 ,也可以用于复数

浮点

7

%E

%e​相同

浮点

8

%g

根据实际情况判断输出%f​或者%e​,会去掉多余的0

浮点

9

%b

输出整型的二进制表现形式

数字

10

%#b

输出二进制完整的表现形式

数字

11

%o

输出整型的八进制表示

整型

12

%#o

输出整型的完整八进制表示

整型

13

%x

输出整型的小写十六进制表示

数字

14

%#x

输出整型的完整小写十六进制表示

数字

15

%X

输出整型的大写十六进制表示

数字

16

%#X

输出整型的完整大写十六进制表示

数字

17

%v

输出值原本的形式,多用于数据结构的输出

任意

18

%+v

输出结构体时将加上字段名

任意

19

%#v

输出完整Go语法格式的值

任意

20

%t

输出布尔值

布尔

21

%T

输出值对应的Go语言类型值

任意

22

%c

输出Unicode码对应的字符

int32

23

%U

输出字符对应的Unicode码

rune​,byte

24

%p

输出指针所指向的地址

指针

使用fmt.Sprintf​或者fmt.Printf​来格式化字符串或者输出格式化字符串,看几个例子

fmt.Printf("%%%s\n", "hello world")
 
fmt.Printf("%s\n", "hello world") 
fmt.Printf("%q\n", "hello world") 
fmt.Printf("%d\n", 2<<7-1)	

fmt.Printf("%f\n", 1e2)	
fmt.Printf("%e\n", 1e2)		
fmt.Printf("%E\n", 1e2)		
fmt.Printf("%g\n", 1e2)		

fmt.Printf("%b\n", 2<<7-1)	
fmt.Printf("%#b\n", 2<<7-1)	
fmt.Printf("%o\n", 2<<7-1)	
fmt.Printf("%#o\n", 2<<7-1)	
fmt.Printf("%x\n", 2<<7-1)	
fmt.Printf("%#x\n", 2<<7-1)	
fmt.Printf("%X\n", 2<<7-1)	
fmt.Printf("%#X\n", 2<<7-1)	

type person struct {
    name    string
    age     int
    address string
}
fmt.Printf("%v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%+v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%#v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%t\n", true)					
fmt.Printf("%T\n", person{})				
fmt.Printf("%c%c\n", 20050, 20051)			
fmt.Printf("%U\n", '码')							   
fmt.Printf("%p\n", &person{})				

使用其它进制时,在%​与格式化动词之间加上一个空格便可以达到分隔符的效果,例如

func main() {
	str := "abcdefg"
	fmt.Printf("%x\n", str)
	fmt.Printf("% x\n", str)
}

该例输出的结果为

61626364656667
61 62 63 64 65 66 67

在使用数字时,还可以自动补零。比如

fmt.Printf("%09d", 1)
// 000000001

二进制同理

fmt.Printf("%09b", 1<<3)
// 000001000

错误情况

格式化字符数量 < 参数列表数量

fmt.Printf("", "") //%!(EXTRA string=)

格式化字符数量 > 参数列表数量

fmt.Printf("%s%s", "") //%!s(MISSING)

类型不匹配

fmt.Printf("%s", 1) //%!s(int=1)

缺少格式化动词

fmt.Printf("%", 1) // %!(NOVERB)%!(EXTRA int=1)

数组与切片

数组的切割得到的切片和数组指向同一片内存,如果需要深度克隆使用以下方法

func main() {
	arr := [5]int{1, 2, 3, 4, 5}
	slice := slices.Clone(arr[:])
	slice[0] = 0
	fmt.Printf("array: %v\n", arr)
	fmt.Printf("slice: %v\n", slice)
}

...(语法糖)

‘…’ 其实是go的一种语法糖。
它的第一个用法主要是用于函数有多个不定参数的情况,可以接受多个不确定数量的参数。
第二个用法是slice可以被打散进行传递。

下面直接上例子:

func test1(args ...string) { //可以接受任意个string参数
    for _, v:= range args{
        fmt.Println(v)
    }
}

func main(){
var strss= []string{
        "qwr",
        "234",
        "yui",
        "cvbc",
    }
    test1(strss...) //切片被打散传入
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

结果:

qwr
234
yui
cvbc
1
2
3
4

其中strss切片内部的元素数量可以是任意个,test1函数都能够接受。

第二个例子:

    var strss= []string{
        "qwr",
        "234",
        "yui",

    }
    var strss2= []string{
        "qqq",
        "aaa",
        "zzz",
        "zzz",
    }
strss=append(strss,strss2...) //strss2的元素被打散一个个append进strss
fmt.Println(strss)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

结果:

[qwr 234 yui qqq aaa zzz zzz]

函数

Go语言不允许函数重载!

返回值

下面是一个简单的函数返回值的例子,Sum​函数返回一个int​类型的值。

func Sum(a, b int) int {
   return a + b
}

当函数没有返回值时,不需要void​,不带返回值即可。

func ErrPrintf(format string, a ...any) {
	_, _ = fmt.Fprintf(os.Stderr, format, a...)
}

Go允许函数有多个返回值,此时就需要用括号将返回值围起来。

func Div(a, b float64) (float64, error) {
	if a == 0 {
		return math.NaN(), errors.New("0不能作为被除数")
	}
	return a / b, nil
}

Go也支持具名返回值,不能与参数名重复,使用具名返回值时,return​关键字可以不需要指定返回哪些值。

func Sum(a, b int) (ans int) {
	ans = a + b
	return
}

和参数一样,当有多个同类型的具名返回值时,可以省略掉重复的类型声明

func SumAndMul(a, b int) (c, d int) {
	c = a + b
	d = a * b
	return
}

不管具名返回值如何声明,永远都是以return​关键字后的值为最高优先级。

func SumAndMul(a, b int) (c, d int) {
	c = a + b
	d = a * b
    // c,d将不会被返回
	return a + b, a * b
}

匿名函数

匿名函数就是没有签名的函数,例如下面的函数func(a, b int) int​,它没有名称,所以我们只能在它的函数体后紧跟括号来进行调用。

func main() {
   func(a, b int) int {
      return a + b
   }(1, 2)
}


Comment