Go语言的特点
- 解决了其他语言的痛点
- 并发编程->大数据,微服务
- 没有对象,没有继承多态,没有泛型,没有try/catch
- 有接口,函数式编程,CSP并发模型(goroutine+channel)
基本语法
- 变量
- 选择,循环
- 指针,数组,容器
面向接口
- 结构体
- duck typing概念
- 组合的思想
函数式编程
- 闭包
- 例题
工程化
- 资源管理,错误处理
- 测试和文档
- 性能调优
并发编程
- goroutine和channel
- 调度器
实战
使用Go语言自主搭建简单分布式爬虫
爬取相亲网站
基础语法
- var 变量 可以规定类型
- const 常量 可以规定类型 (一般不大写,首字母大写代表Project)
const filename = "abc"
- const数值可作为各种类型使用
const a,b = 3,4
var c int = int(math.Sqrt(a*a + b * b ))
- 常量可以用()括起来,节省代码
- 变量类型写在变量名之后
- 编译器可推测变量类型
- 没有char,只有rune(32位)
- 原生支持复数类型
普通枚举类型
const (
cpp = iota
_
python
golang
js
fmt.Println(cpp,js,python,golang) 输出:0,4,2,3
自增值枚举类型
const (
b = 1 << (10 * iota)
kb
mb
gb
tb
pb
fmt.Println(b,kb,mb,gb) 输出:1,1024,1048576,1073741824....
条件语句
- if的条件不需要括号
- if的条件里可以赋值
- if的条件里赋值的变量作用域就在这个if语句里
- switch
- switch会自动break,除非使用fallthrough
- switch后面可以没有表达式
- 没有while
const filename = "abc.txt"
if contents, err := ioutil.ReadFile(filename); err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
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"
}
return g
}
- for
- for的条件里不需要括号
- for的条件里可以省略初始条件,结束条件,递增表达式
转二进制函数
func convertToBin(n int) string {
result := ""
if n == 0 {
return strconv.Itoa(n)
}
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)
}
printFileContents(file)
}
func printFileContents(reader io.Reader) {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
func forever() {
for { // 死循环
fmt.Println("abc")
}
}
函数
- 支持返回多个值
- 函数返回多个值时可以起名字
- 仅用于非常简单的函数
- 对于调用者而言没有区别
- 函数参数也可以是函数
- 可变参数列表
- 返回值类型写在最后面
- 没有默认参数,可选参数
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)
}
}
报错
if result, err := eval(3, 4, "x"); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println(result)
}
func div(a, b int) (q, r int) {
return a / b, a % b
}
相当于
func div(a,b int) (q,r int) {
q = a / b
r = a % b
return
}
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
}
指针
- 指针不能运算
- Go语言只有值传递一种方式
func swap(a,b *int){
*b,*a=*a,*b
}
或者(推荐)
func swap(a, b int) (int, int) {
return b, a
}