golang 知识点总结
此系列文档根据慕课网 golang视频总结的个模块知识点汇总。
1.1 变量定义
1.1.1 使用 var 关键字
- var a, b, c bool
- var s1, s2 string = “hello”, “world”
- 可放在函数内,或直接放在包内
- 使用 var() 集中定义变量
1.1.2 让编译器自动决定类型
- var a, b, i, s1, s2 = true, false, 3, “hello”, “world”
1.1.3 使用 := 定义变量(只能在函数内部)
- a, b, i, s1, s2 := true, false, 3, “hello”, “world”
1.2 内建变量类型
- bool, string
- (u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr
- byte, rune
- float32, float4, complex64, complex128
1.2.1 强制类型转换
- 类型转换是强制的
- var a, b int =3 ,4
- var c int = math.Sqrt(a * a + b * b) X错误写法
- var c int = int(math.Sqrt(float63(a * a + b * b)) √ 正确写法
- ? 如果算出来是4.999 => int出来是变成 4
package main
import (
"math"
"fmt"
)
func triangle() {
var a, b int = 3, 4
var c int
// 这里 go 不能隐式的转换类型,所以要在显示转换加入int()
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(c)
}
func main() {
triangle()
}
// => 5
变量定义要点回顾
- 变量类型写在变量名之后
- 编译器可推测变量类型
- 没有 char 只有 rune
- 原生支持复数类型 complex
1.3 常亮与枚举
1.3.1 常量
- const filename = “abc.txt”
- const 数值可作为各种类型使用(不用转换)
- const a, b =3, 5
- var c int = int(math.Sqrt(a * a + b * b)) 这里就不用将a ,b 转化为float64.
1.3.2 枚举类型的常量
普通枚举类型
自增值枚举类型
/*
* 枚举类型的常量
*/
func enums() {
const (
cpp = iota
_ // 这里的 _ 表示不用次常量,但要占位置。
python
golang
javascript
)
// b , kb, mb, gb, tb ,pb
const (
b = 1 << (10 * iota) // 二进制为1 左移 多少位
kb
mb
gb
tb
pb
)
fmt.Println(cpp, javascript, python, golang)
// => 0 4 2 3
fmt.Println(b , kb, mb, gb, tb ,pb)
}
1.4 条件语句
1.4.1 if 条件判断
package main
import(
"fmt"
"io/ioutil"
)
func main(){
const filename = "abc.txt"
if contents, err := ioutil.ReadFile(filename); err != nil {
fmt.Println(err)
} else {
// fmt.Println(contents)
fmt.Printf("%s\n", contents)
}
fmt.Println(consts) // => undefined: consts
}
- if 的条件里可以赋值
- if 的条件里赋值的变量作用域只能在这个 if 语句里
1.4.2 switch 条件判断
- switch 会自动break,除非你不break 则用 fallthrough
- switch 后可以没有表达式
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
default:
panic("unsupported operator:" + op)
}
return result
}
func grade(score int) string {
g := ""
switch {
case score < 0 || score > 100:
panic(fmt.Sprintf(
"Wrong scor: %d", score))
case score < 60:
g = "F"
case score < 80:
g = "C"
case score < 90:
g = "B"
case score <= 100:
g = "A"
}
return g
}
func main() {
fmt.Println(
grade(0), // F
grade(59), // F
grade(60), // C
grade(82), // B
grade(99), // A
grade(100), // A
// grade(101),
// grade(-3),
)
fmt.Println(
eval(10, 90, "+"), // 100
eval(5, 10, "-"), // 5
)
}
1.5 循环
- for 的条件里不需要括号
- for 的条件里可以省略初试条件,结束条件,递增表达式
// printFile("abc.txt")
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())
/* => aaaa
golang no.1
javascript
node.js
*/
}
}
func forever() {
// go 语言的死循环
for {
fmt.Println("abc")
}
}
- 省略初试条件,相当于while
- 全部省略,死循环
1.6 函数
- 函数可返回多个值
- 函数返回多个值时可以起名字(不要乱用,仅用于非常简单的函数, 对于调用者而言没有区别)
- 可变参数列表(没有默认参数,可选参数)
package main
import (
"math"
"runtime"
"reflect"
"fmt"
)
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) // 这里用不到返回值r,如果加上会报错,因为没有用到
return q, nil
default:
return 0, fmt.Errorf("unsupported operation: %s", op)
}
}
// 可返回多值
func div(a, b int) (q, r int) {
return a / b, a % b
}
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)\n",
opName, a, b)
return op(a, b)
}
// 可变参数列表
func sum(numbers ...int) int {
s := 0
for i := range numbers {
s += numbers[i]
}
return s
}
// func Pow(a, b int) int {
// return int(math.Pow(float64(a), float64(b)))
// }
func main() {
fmt.Println(eval(3, 4, "*"))
if result, err := eval(3, 4, "x"); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println(result)
}
q, r := div(13, 3)
fmt.Println(q, r)
fmt.Println(apply( // 函数式编程
func (a, b int) int {
return int(math.Pow(float64(a), float64(b)))
},3, 4))
fmt.Println(sum(1, 2, 3))
}
1.7 ++指针++(重要)
go 语音的指针比较 C 语音更为简单:
- 指针不能运算
1.7.1 参数传递
许多语言如: Java Python JavaScript 都是引用传递参数(就是直接调用自身底层数据,它会改变) - go 语言只有 值传递一种方式(调用的是复制的值,不会改变底层数据,除非用指针)
// 指针
func swap(a, b *int) {
*b, *a = *a, *b
}
a, b := 3, 4
swap(&a, &b)
fmt.Println(a, b) // => 4, 3