go基础

基础

方法和接口

并发

基础

每个 Go 程序都是由包组成的。
程序运行的入口是包 main
这个程序使用并导入了包 "fmt" 和 "math/rand"
package main

import (
    "fmt"
    "math/rand"
)

func main() {
    fmt.Println("My favorite number is", rand.Intn(10))
}
"打包"导入语句
import "fmt"
import "math"
以下打包的导入语句是更好的形式
import (
    "fmt"
    "math"
)
在导入了一个包之后,就可以用其导出的名称来调用它。在 Go 中,首字母大写的名称是被导出的。
错误的用法
math.pi
正确的用法
math.Pi

函数

函数可以没有参数或接受多个参数。
在这个例子中,add 接受两个 int 类型的参数。
注意: 类型在变量名之后
package main

import "fmt"

func add(x int, y int) int {
    return x + y
}

func main() {
    fmt.Println(add(42, 13))
}
当两个或多个连续的函数命名参数是同一类型,则除了最后一个类型之外,其他都可以省略。
在这个例子中 方法 add被缩写为,
func add(x, y int) int {
    return x + y
}
函数可以返回任意数量的返回值
func swap(x, y string) (string, string) {
    return y, x
}

变量

var 语句定义了一个变量的列表;跟函数的参数列表一样,类型在后面。
var i int
初始化变量
var i, j int = 1, 2
在函数中,:= 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。
i := 3
Go 的基本类型
bool
string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // uint8 的别名
rune // int32 的别名 代表一个Unicode码
float32 float64
complex64 complex128
零值
变量在定义时没有明确的初始化时会赋值为零值。
零值是:
数值类型为 `0`,
布尔类型为 `false`,
字符串为 `""`(空字符串)。
类型转换
注意: Go 的在不同类型之间的赋值时需要显式转换
var i int = 42
var f float64 = float64(i)

或者,更加简单的形式:

i := 42
f := float64(i)
常量
const Pi = 3.14

常量组
const (
    Big   = 1 << 100
    Small = Big >> 99
)

流程控制语句

for
sum := 0
for i := 0; i < 10; i++ {
    sum += i
}
fmt.Println(sum)

可以让前置、后置语句为空
sum := 1
for ; sum < 1000; {
    sum += sum
}
fmt.Println(sum)
C 的 while 在 Go 中叫做 for
sum := 1
for sum < 1000 {
    sum += sum
}
fmt.Println(sum)
死循环
for {
}
if
if x < 0 {
    return x
}
if 便捷语句可以在条件之前执行一个简单的语句
if v := math.Pow(x, n); v < lim {
    return v
}
return lim

便捷语句定义的变量同样可以在任何对应的 else 块中使用
if v := math.Pow(x, n); v < lim {
    return v
} else {
    fmt.Printf("%g >= %g\n", v, lim)
}
// 这里开始就不能使用 v 了
return lim
switch 从上到下的执行,当匹配成功的时候停止
switch os := runtime.GOOS; os {
case "darwin":
    fmt.Println("OS X.")
case "linux":
    fmt.Println("Linux.")
default:
    // freebsd, openbsd,
    // plan9, windows...
    fmt.Printf("%s.", os)
}
defer 语句会延迟函数的执行直到上层函数返回。
func main() {
    defer fmt.Println("world")

    fmt.Println("hello")
}
会先打印hello 后打印world

func main() {
    fmt.Println("counting")

    for i := 1; i <= 10; i++ {
        defer fmt.Println(i)
    }

    fmt.Println("done")
}

打印结果如下:
counting
done
10
9
8
7
6
5
4
3
2
1

复杂类型

指针保存了变量的内存地址。
i, j := 42, 2701

p := &i        
fmt.Println(*p)
*p = 21        
fmt.Println(i) 

p = &j         
*p = *p / 37   
fmt.Println(j) 

结果如下:
42
21
73
一个结构体(struct)就是一个字段的集合。
type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    v.X = 4
    fmt.Println(v.X)  //结构体字段使用点号来访问。
}
数组
var a [10]int //定义变量 a 是一个有十个整数的数组,数组不能改变大小
slice, []T是一个元素类型为 T 的 slice。
p := []int{2, 3, 5, 7, 11, 13} 
对 slice 切片
p := []int{2, 3, 5, 7, 11, 13}
fmt.Println("p ==", p)
fmt.Println("p[1:4] ==", p[1:4])

// 省略下标代表从 0 开始
fmt.Println("p[:3] ==", p[:3])

// 省略上标代表到 len(s) 结束
fmt.Println("p[4:] ==", p[4:])
构造 slice, slice 由函数 make 创建,这会分配一个零长度的数组并且返回一个 slice 指向这个数组
a := make([]int, 5)  // len(a)=5
向 slice 添加元素是一种常见的操作,因此 Go 提供了一个内建函数 append
var a []int
a = append(a, 2, 3, 4)
for 循环的 range 格式可以对 slice 或者 map 进行迭代循环
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

for i, v := range pow {
    fmt.Printf("2**%d = %d\n", i, v)
}
map
map 在使用之前必须用 make 而不是 new 来创建;值为 nil 的 map 是空的,并且不能赋值,必须有键名
type Vertex struct {
    Lat, Long float64
}

var m map[string]Vertex

func main() {
    m = make(map[string]Vertex)
    m["Bell Labs"] = Vertex{
        40.68433, -74.39967,
    }
    fmt.Println(m["Bell Labs"])
}
修改 map
m := make(map[string]int)

m["Answer"] = 42
fmt.Println("The value:", m["Answer"])

m["Answer"] = 48
fmt.Println("The value:", m["Answer"])

delete(m, "Answer")
fmt.Println("The value:", m["Answer"])

v, ok := m["Answer"]
fmt.Println("The value:", v, "Present?", ok)
函数也是值
hypot := func(x, y float64) float64 {
    return math.Sqrt(x*x + y*y)
}

fmt.Println(hypot(3, 4))

方法

Go 没有类。对包中的 任意 类型包括,结构体定义任意方法
type MyFloat float64

func (f MyFloat) Abs() float64 {
    if f < 0 {
        return float64(-f)
    }
    return float64(f)
}


以下是结构体定义方法
type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

接收者为指针的方法
type Vertex struct {
    X, Y float64
}

func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := &Vertex{3, 4}
    v.Scale(5)
    fmt.Println(v, v.Abs())
}

接口

接口类型是由一组方法定义的集合

猜你喜欢

转载自www.cnblogs.com/spectrelb/p/9032875.html