1、定义变量
局部变量、全局变量
使用 关键字 var 定义变量,自动初始化为 0 值。
# 方式一 :
func variable() {
var a int
var s string
}
# 方式二 :
func variableInitialValue() {
var a, b int = 3, 4
var s string = "abc"
}
# 方式三 : 推荐
func variableTypeDeduction() {
a, b, c, s , s1 := 3, 4.12, "abc", true, [2]int{1, 2}
}
# 方式四 :
var s , a = "abc" , 1
# 全局变量
var (
a = 3
b = 4
)
2、输出格式
# Go 为常规 Go 值的格式化设计提供了多种打印方式。
1、结构体
1、打印结构体
p := point{1, 2}
fmt.Printf("%v\n", p) // {1 2}
2、如果是结构体,%+v 的格式化输出内容将包括结构体的字段名
fmt.Printf("%+v\n", p) // {x:1 y:2}
3、如果是结构体,%#v 形式则输出这个值的 Go 语法表示。例如,值的运行源代码片段。
fmt.Printf("%#v\n", p) // main.point{x:1, y:2}
2、布尔值
fmt.Printf("%t\n", true) // ture
3、数字
fmt.Printf("%d\n", 123) // 十进制 123
fmt.Printf("%b\n", 14) // 二进制 1110
fmt.Printf("%c\n", 67) // 67对应的ascii c
fmt.Printf("%x\n", 456) // 16进制 1c8
fmt.Printf("%f\n", 78.9) // 最基本的十进制格式化 78.900000
fmt.Printf("%e\n", 123400000.0) // 科学计数法 1.234000e+08
控制宽度
fmt.Printf("|%6d|%6d|\n", 12, 345) // | 12| 345|
fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45) // | 1.20| 3.45|
fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45) // |1.20 |3.45 |
fmt.Printf("|%6s|%6s|\n", "foo", "b") // | foo| b|
4、字符串
fmt.Printf("%s", "\"string\"") // "string"
fmt.Printf("%q\n", "\"string\"") // "\"string\""
fmt.Printf("%q", "string") // "string"
5、指针
a := 3
p := &a
fmt.Printf("%p\n", &p) // a 的地址是 0xc0000ac018
fmt.Printf("%d", *p) // *p 的值是3
6、数组
7、获取变量的类型
fmt.Println(fmt.Sprintf("%T", size))
# fmt 包:
1、打印输出类:
fmt.Println(...interface{})//打印后换行
fmt.Print()//打印
fmt.Printf(string, ...interface{})//格式化打印
读取键盘:
Scanln()
Scanf()
拼接字符串:
Sprint()
Sprintf()
Sprintln()
获取error对象
Errorf()
eg :
fmt.Println("aa", "bb", "cc")
fmt.Printf("name是:%s,年龄是:%d\n", "王二狗", 30)
s1 := fmt.Sprint("helloworld", 100, 3.14, "memeda") //获取字符串
fmt.Println(s1)
s5 := fmt.Sprintf("name:%s,年龄:%d", "王二狗", 30) // name:王二狗,年龄:30
fmt.Println(s5)
3 变量类型
![]()
# bool , string
# (u)int, (u)int8 (u)int16 (u)int32 (u)int32 (u)int64 uintptr
# byte , rune
# float32, float64, complex64, complex128
# 字符类型是 uint8
# 复合类型
array, slice, map, function
# 数据类型的分类:
值类型:
int,float,bool,string,array,struct
引用类型
slice,map,function
View Code
4、常量定义
# const
const a, b = 3, 4
const filename = "abc.txt"
或者
const (
a = 3
b = 4
str = "name"
)
# 在常量组中,如不提供类型和初始化值,那么视为与上一常量相同
const (
s = "abc"
x // x = "abc"
)
5 条件语句
# if
func bounded(v int) int {
if v > 100 {
return 100
} else if v < 0 {
return 0
}
return v
}
# switch
switch 会自动 break, 除非使用 fallthrough
func eval(a, b int, op string) int {
var result int
switch op {
case "+":
result = a + b
case "-":
result = a - b
case "*":
result = a * b
case "/":
result = a / b
}
return result
}
// 调用
fmt.Printf("%d", eval(1, 3, "+"))
6 循环
# for
func loopAdd(n int) int {
sum := 0
for i := 0; i < 100; i++ {
sum += i
}
return sum
}
// 调用
fmt.Printf("%d", loopAdd(100))
// 无限循环
for {
}
// for 循环退出
i := 0
for {
i++
if i == 5 {
break
} else {
fmt.Println("i = ", i)
}
}
# 没有 while
7 函数
# 可以返回多个值
func div(a, b int) (q, r int) {
return a / b, a % b
}
// 调用
q, r := div(19, 5)
fmt.Printf("q = %d, r = %d", q, r)
// 在函数中传递任意多个数字
func add(merbers ...int) int {
sum := 0
for i := range merbers {
sum += merbers[i]
}
return sum
}
fmt.Printf("q = %d", add(1, 2, 3))
8 指针
# pointer,指针
概念:存储了另一个变量的内存地址的变量。
# 指针的类型:*int,*float,*string,*array,*struct
指针中存储的数据的类型:int,float,string,array,struct
# %T 指针的类型
# %p 地址
a := 10
fmt.Println("a的数值是:", a) //10
fmt.Printf("a的类型是:%T\n", a) //int
fmt.Printf("a的地址是:%p\n", &a) //0xc42001c0c8
func main() {
a := 10
var p1 *int
p1 = &a
var p2 **int
fmt.Println(p2)
p2 = &p1
fmt.Println("p2的数值:", p2) //0xc0000ac018
fmt.Println("p2的数值,p1的地址,对应的数据:", *p2) //p2的数值,p1的地址,对应的数据: 0xc0000b2008
fmt.Println("p2中存储的地址对应的数值,在对应的数值:", **p2) //p2中存储的地址对应的数值,在对应的数值: 10
}
# 深浅拷贝
深拷贝:拷贝数据的副本。对原始数据没有影响
值类型的数据,默认都是深拷贝
int,float,string,bool,array,struct
浅拷贝:拷贝的是数据的地址。
引用类型的数据,默认都是浅拷贝
slice,map,function
# 数组的深拷贝
arr1 := [4]int{1, 2, 3, 4}
arr2 := arr1
# 数组的浅拷贝
arr3 := &arr1
(*arr3)[0] = 100
func fun4(p2 *[4]int) {
fmt.Println("函数中数组:", p2)
p2[0] = 200
fmt.Println("函数中数据:", p2)
}
func fun3(arr2 [4]int) { //arr2 = arr1,数组是值数据
fmt.Println("函数中数组:", arr2) //[1,2,3,4]
arr2[0] = 100
fmt.Println("函数中数组:", arr2) //[100,2,3,4]
}
# 数组指针:首先是一个指针,一个数组的地址。
存储的是数组的地址
*[4]int
# 指针数组:首先是一个数组,存储的数据类型是指针
[4]*Type
*[5]float64,指针,一个存储了5个浮点数据的数组的指针
*[3]string,指针,一个数组的指针,数组中存储了3个字符串
[5]*float64,数组,存储5个float的数据的地址
*[5]*float64,指针,一个数组的指针,数组中存储5个float的数据的地址
*[3]*string,指针,数组的指针,3个字符串的地址
**[4]string,指针,存储了4个字符串数据的数组的指针的指针
**[4]*string,指针,存储了4个字符串的数据的地址的数组,的指针的指针。。
# eg : 数组指针
a := 1
b := 2
c := 3
d := 4
arr2 := [4]int{a, b, c, d}
arr3 := [4]*int{&a, &b, &c, &d}
fmt.Println(*arr3[0])
# eg : 指针数组
arr1 := [4]int{1, 2, 3, 4}
var p1 *[4]int
p1 = &arr1
(*p1)[0] = 100 //简写
p1[0] = 200
# 指针和函数
函数指针: 一个指针,指向了一个函数的指针。
因为go语言中,function,默认看作一个指针,没有*。
slice,map,function是引用类型的数据,存储的就是数据的地址。看作一个默认的指针,没有*
指针函数:一个函数,该函数的返回值是一个指针。
# eg
func fun2() [4]int { //普通函数
arr := [4]int{1, 2, 3, 4}
return arr
}
func fun3() *[4]int { //指针函数
arr := [4]int{1, 2, 3, 4}
return &arr
}
arr1 := fun2()
arr2 := fun2()
fmt.Printf("arr1的类型:%T,地址:%p,数值:%v\n", arr1, &arr1, arr1)
fmt.Printf("arr2的类型:%T,地址:%p,数值:%v\n", arr2, &arr2, arr2)
p3 := fun3()
p4 := fun3()
fmt.Printf("p3:%T,地址:%p,数值:%v\n", p3, p3, p3)
fmt.Printf("p4:%T,地址:%p,数值:%v\n", p4, p4, p4)
9 日期