变量定义
定义变量
关键字 var
, :
函数内部定义
-
变量名: 写在前面; 类型: 写在后面
func variable() { var a int var s string fmt.Printf("%d %q\n",a, b, s) }
-
变量是有初始值的
类型 初始值 int 0 string 空字符串 bool false float 0
-
变量初始也可以赋值, 可以多个变量一起定义, 定义的变量一定要使用, 否则会报红
// 初始变量赋值 func variableInitialValue() { var a, b int = 3, 5 var s string = "abc" fmt.Println(a, b, s) }
-
编译器可以自动判断变量类型, 所以可以省略类型
// 自动判断变量类型 func variableTypeDeduction() { var a, b, c, s = 3,4, true, "string" fmt.Println(a, b, c, s) }
-
定义变量也可以使用
:
, 省略var
func variableShorter() { a, b, c, s := 3,4, true, "string" b = 5 // 再次赋值, 不能用 := 会报错 fmt.Println(a, b, c, s) }
:
定义变量, 更简洁, 知道哪个更合适了吧
函数外部定义
-
函数外部定义变量, 用
var
, 或 其他 关键字, 不能用:
var ( aa = 3 bb = "kkk" cc = true )
并不是全局变量, 属于包内部变量
小结
-
使用
var
关键字; 可以放在函数内, 或直接放在包内; 使用var()
集中定义变量var a, b, c bool var s1, s2 string = "hello", "world"
-
编译器可以自动判断类型
var a, b, c, s1, s2 = true, false, 3, "hello", "world"
-
使用
:=
定义变量; 只能在函数内部使用a, b, c, s1, s2 := true, false, 3, "hello", "world"
内建变量类型
变量类型
bool, string
整数类型
前缀带 (u)
无符号整型, 不带 (u)
有符号整型
规定长度, 不规定长度; 若不规定, 则跟随系统
- (u)int
- (u)int8
- (u)int16
- (u)int32
- (u)int64
- uintptr
byte rune
- byte 8位
- rune 字符型,32位, 相当于char
浮点数
- float32
- float64
- complex64 复数: 实部, 虚部 分别 float32位
- complex128 复数: 实部, 虚部 分别 float64位
强制类型转换
-
只有强制类型转换
// 强制类型转换 func triangle() { var a, b int = 3, 4 var c int // math.Sqrt() 需要 float, 且返回 float , 需要强转, 定义变量 c 是 int, 所以又需要强转 c = int(math.Sqrt(float64(a * a + b * b))) fmt.Println(c) }
常量与枚举
常量
定义
- 关键字
const
func consts() { const filename = "abc.txt" const a, b = 3, 4 // 常量未定义类型, 既可以做 int, 也可以做 float }
常量未定义类型, 既可以做 int, 也可以做 float
也可以定义在函数外部, 同样,只作用于包内部
-
也可以定义常量组
func consts() { const ( filename = "abc.txt" a, b = 3, 4 // 常量未定义类型, 既可以做 int, 也可以做 float ) }
关于常量大小写的问题,
Go
和其他语言有点不同
枚举类型
定义
- 使用
const
关键字定义func enums() { const ( cpp = 0 java = 1 php = 2 python = 3 ) fmt.Println(cpp, java, php, python) } // 使用 iota 简化, 同上, iota 可以进行表达式运算 func enums() { const ( cpp = iota java php python ) const ( b = 1 << (10 * iota) kb mb gb tb pb ) fmt.Println(cpp, java, php, python) fmt.Println(b, kb, mb, gb, tb, pb ) }
条件语句
if
if
条件里不需要括号
```
func main() {
const filename = "abc.txt"
contents, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
// 简化
if contents, err := ioutil.ReadFile(filename); err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
}
```
switch
switch
会自动break
, 除非使用fallthrough
-
switch
后可以没有表达式,case
里面写表达式func grade(score int) string { g := "" switch { case score < 0 || score > 100: panic(fmt.Sprintf("Wrong score: %d", score)) case score < 60: g = "F" case score < 80: g = "C" case score < 90: g = "B" case score < 100: g = "A" default: panic(fmt.Sprintf("Wrong score: %d", score)) } return g }
循环
for
for
的条件里不需要括号-
for
的条件里可以省略初始条件, 结束条件, 递增表达式func convertToBin(n int) string { result := "" for ; n > 0; n /= 2 { lsb := n %2 result = strconv.Itoa(lsb) + result } return result } func printFile(filename string) { file, err := os.Open(filename) if err != nil { panic(err) } scanner := bufio.NewScanner(file) for scanner.Scan() { fmt.Println(scanner.Text()) } } func forever() { for { fmt.Println("abc...") } }
小结
-
for
,if
后面的条件没有括号 -
if
条件里也可定义变量 - 没有
while
-
switch
不需要break
, 也可以直接switch
多个条件
函数
定义
-
函数名在前, 类型在后
"eval" 函数名, int 返回值类型 参数 同样, 参数在前, 类型在后 func eval(a, b int, op string) int { switch op { case "+": return a + b case "-": return a - b case "*": return a * b case "/": return a / b default: panic("unsupported operation: " + op) } } // 可以同时返回两个值, 若只想接收其中一个值, 可以再次声明 2 个变量接收, 使用 "_" 代替其中一个, 就可以接收其中一个了 func div (a, b int) (int, int) { return a / b, a % b } // 多值返回 func eval(a, b int, op string) (int, error) { switch op { case "+": return a + b, nil case "-": return a - b, nil case "*": return a * b, nil case "/": q, _ := div(a, b) return q, nil default: return 0, fmt.Errorf("unsupported operation: %s", op) } }
函数式编程
-
函数式编程
func apply(op func(int, int) int, a, b int) int { p := reflect.ValueOf(op).Pointer() opName := runtime.FuncForPC(p).Name() fmt.Printf("Calling function %s with args " + "(%d, %d)", opName, a, b) return op(a, b) }
-
匿名函数
func main() { // 匿名函数 fmt.Println(apply(func(a int, b int) int { return int(math.Pow(float64(a), float64(b))) }, 3, 4)) }
-
可变参数列表函数
func sum(numbers ...int) int { s := 0 for i := range numbers { s += numbers[i] } return s }
小结
- 返回值类型写在最后面
- 可以返回多个值
- 函数可以作为参数
- 没有默认参数, 可选参数, 只有可变参数列表
指针
指针不能做运算
参数传递
只有值传递一种方式
值传递
// 交换两个数值
func swap(a, b *int) {
*b, *a = *a, *b
}
func swap2(a, b int) (int, int) {
return b, a
}
总结
- 变量类型在前, 变量类型在后
- 使用
var
,:
关键字声明变量 - 只有强制类型转换
-
if
条件里不需要括号 -
switch
会自动break
, 除非使用fallthrough
-
switch
后可以没有表达式,case
里面写表达式 -
for
的条件里不需要括号 -
for
的条件里可以省略初始条件, 结束条件, 递增表达式 - 函数定义, 同样函数名在前, 类型在后
- 返回值类型写在最后面
- 可以返回多个值
- 函数可以作为参数
- 没有默认参数, 可选参数, 只有可变参数列表
- 指针不能做运算
- 只有值传递一种方式