Go语言基础
Posted 想考北航的小刺猬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言基础相关的知识,希望对你有一定的参考价值。
go语言由package构成,go语言的实现使用传统的编译链接模式产生可执行文件。
go语言的特色:
- 支持环境采纳模式,例子就是不需声明变量类型,编译器会自动根据赋值的类型而采用相应的类型。
- 编译时间短
- 内置并行的支持:轻量级的进程、channel、select语句
- 支持接口和类型的嵌入
- 不需要外部依赖产生静态链接的本地二级制文件
Keyword
Basic
Package
每个go程序都是由packages组成,程序在package main中开始运行。
一般来说包名和导入路径的最后一个元素相同,例如"math/rand"中,就是导入rand包。
package main
import (
"fmt"
"math/rand"
"time"
)
//设置随机数种子,根据当前时间,来产生不同的随机数。如果不设置种子,那么由于每次程序被执行的环境是确定的,所以每次运行程序得到的结果是一样的
func main()
//rand.Seed(time.Now().UnixNano())
fmt.Println("My favorite number is",rand.Intn(100))
fmt.Println("My favorite number is",rand.Intn(100))
import
将imports组合到括号中,分解导入语句。
import(
"fmt"
"math"
)
//也可以写成多导入形式,但分解导入是一种比较好的形式
import "fmt"
import "math"
Exported names
首字母大写的名字是Exported names,也就是可以被外部调用的,导入一个包的时候可以只参考Exported names,非输出名字不会被包外访问。
package main
import (
"fmt"
"math"
)
func main()
fmt.Println(math.Pi)
Function
- 一个函数可以携带0个或者多个参数。
- 类型在变量名之后,返回值类型也位于函数名后面,例如func add1(x, y int) int中的第二个int。同一类型变量可以省略前面的变量类型。
- 函数也可以返回多个返回值。
- 返回值可以是指定的,如split中的函数返回值声明处(x, y int),制定了x和y为返回值,在函数体内部即可用return结尾,成为裸返回
package main
import "fmt"
func add(x int, y int) int
return x + y
func add1(x, y int) int
return x + y
func swap(x, y string) (string, string)
return y, x
func split(sum int) (x, y int)
x = sum * 4 / 9
y = sum - x
return
func main()
fmt.Println(add(42, 13))
Variables
- var语句声明了一个变量列表,一个也可以,类型放在最后
- var可以在包级别或者函数级别
- var声明每个变量可以包含初始化值,初始化值出现,类型可以被省略,变量将会用初始化值的类型
- 函数内部短变量赋值 " := ",隐含类型的变量声明。函数外部不可用
package main
import "fmt"
var c, python, java bool
var i, j int = 1, 2
func main()
var i int
k := 1
fmt.Println(i, c, python, java, k)
Basic types
- bool
- string
- int int8 int16 int32 int64
- uint uint8 uint16 uint32 uint64 uintptr
- byte //uint8的别名
- rune //int32的别名,表示一个unicode代码指针
- float32 float64
- complex64 complex128
Type conversions
package main
import (
"fmt"
"math"
)
func main()
var x, y int = 3, 4
var f float64 = math.Sqrt(float64(x*x + y*y))
var z uint = uint(f)
fmt.Println(x, y, z)
var i int
j := i // j is an int
Constants
常量声明const关键字,常量不能用:=来声明和赋值。
format:const identifier [type] = value //type可以省略
const Pi = 3.14
const(
a = "abc"
b = len(a)
c = unsafe.Sizeof(a)
)
iota常量可以被编译器修改的常量,iota在const关键字出现的时候被置为0,const中每增加一行将使iota计数一次。
流控制语句
For
初始值可以不在三个组件中出现
package main
import "fmt"
func main()
sum := 0
for i := 0; i < 10; i++
sum += i
fmt.Println(sum)
package main
import "fmt"
func main()
sum := 1
for ; sum < 1000;
sum += sum
fmt.Println(sum)
package main
import "fmt"
//go中的while用for替换
func main()
sum := 1
for sum < 1000
sum += sum
fmt.Println(sum)
package main
func main()
for
If
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string
if x < 0
return sqrt(-x) + "i"
return fmt.Sprint(math.Sqrt(x))
func main()
fmt.Println(sqrt(2), sqrt(-4))
Switch
package main
import (
"fmt"
"runtime"
)
func main()
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.\\n", os)
Defer
推迟执行函数到主程序结束之前
package main
import "fmt"
func main()
var i = 6
defer fmt.Println(i)
fmt.Println("hello")
Stacking defers
package main
import "fmt"
func main()
fmt.Println("counting")
for i := 0; i < 10; i++
defer fmt.Println(i)
fmt.Println("done")
Break
- 用于跳出循环,并开始执行循环之后的语句
- switch中case执行后跳出
- 多重循环可以使用标号跳出循环
Continue
- 跳出本次循环
- 可以使用标号跳出循环
Goto
- 跳转到标号处,无条件转移
struct、slice和map
Pointers
声明和C语言差不多,但是不能进行指针的计算。
var p *int
i := 42
p = &i
Struct
type Vertex struct
X int
Y int
func main()
v := Vertex1, 2
v.X = 4
fmt.Println(v.X)
Struct Literals
type Vertex struct
X, Y int
var (
v1 = Vertex1, 2 // has type Vertex
v2 = VertexX: 1 // Y:0 is implicit
v3 = Vertex // X:0 and Y:0
p = &Vertex1, 2 // has type *Vertex
)
Arrays
package main
import "fmt"
func main()
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
primes := [6]int2, 3, 5, 7, 11, 13
fmt.Println(primes)
Slices
slice不会存储任何数据,只是一个数组的引用,修改slice的元素会直接修改原位置数据
package main
import "fmt"
func main()
primes := [6]int2, 3, 5, 7, 11, 13
var s []int = primes[1:4]
fmt.Println(s)
package main
import "fmt"
func main()
q := []int2, 3, 5, 7, 11, 13
fmt.Println(q)
r := []booltrue, false, true, true, false, true
fmt.Println(r)
s := []struct
i int
b bool
2, true,
3, false,
5, true,
7, true,
11, false,
13, true,
fmt.Println(s)
cap和len可以计算容量和长度:
fmt.Printf("len=%d cap=%d %v\\n", len(s), cap(s), s)
0值的slice是一个nil,空值
package main
import "fmt"
func main()
var s []int
fmt.Println(s, len(s), cap(s))
if s == nil
fmt.Println("nil!")
Creating a slice with make
用内置make函数创建slice,创建动态数组,make分配一个初始化为0的数组,返回对应数组的一个切片。
package main
import "fmt"
func main()
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
func printSlice(s string, x []int)
fmt.Printf("%s len=%d cap=%d %v\\n",
s, len(x), cap(x), x)
Slices of slices
package main
import (
"fmt"
"strings"
)
func main()
// Create a tic-tac-toe board.
board := [][]string
[]string"_", "_", "_",
[]string"_", "_", "_",
[]string"_", "_", "_",
// The players take turns.
board[0][0] = "X"
board[2][2] = "O"
board[1][2] = "X"
board[1][0] = "O"
board[0][2] = "X"
for i := 0; i < len(board); i++
fmt.Printf("%s\\n", strings.Join(board[i], " "))
Appending to a slice
func append(s []T, vs …T) []T
append的第一个参数s是一个T类型的切片,其余的是要追加到切片的T值。
append的结果值是一个包含原始切片的所有元素加上提供的值的切片。
如果s的支持数组太小,不能容纳所有给定的值,则会分配一个更大的数组。返回的切片将指向新分配的数组。
package main
import "fmt"
func main()
var s []int
printSlice(s)
// append works on nil slices.
s = append(s, 0)
printSlice(s)
// The slice grows as needed.
s = append(s, 1)
printSlice(s)
// We can add more than one element at a time.
s = append(s, 2, 3, 4)
printSlice(s)
func printSlice(s []int)
fmt.Printf("len=%d cap=%d %v\\n", len(s), cap(s), s)
Range
Range形式的for循环迭代一个slice或者map,有两个返回值,第一个是索引,第二个是索引值对应元素的拷贝。
package main
import "fmt"
var pow = []int1, 2, 4, 8, 16, 32, 64, 128
func main()
for i, v := range pow
fmt.Printf("2**%d = %d\\n", i, v)
通过"_"符号来跳过某个返回值:
for i, _ := range pow
for _, value := range pow
//如果只想要索引也可以写成如下形式
for i := range pow
Maps
key-value对
package main
import "fmt"
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"])
package main
import "fmt"
type Vertex struct
Lat, Long float64
var m = map[string]Vertex
"Bell Labs": Vertex
40.68433, -74.39967,
,
"Google": Vertex
37.42202, -122.08408,
,
func main()
fmt.Println(m)
类型名可以省略
var m = map[string]Vertex
"Bell Labs": 40.68433, -74.39967,
"Google": 37.42202, -122.08408,
- 插入或者更新元素
m[key] = elem
- 取回元素
elem = m[key]
- 删除元素
delete(m, key)
- 测试元素
elem, ok = m[key]
Function values
函数可以作为数值传递。
Function closures
package main
import "fmt"
func adder() func(int) int
sum := 0
return func(x int) int
sum += x
return sum
func main()
pos, neg := adder(), adder()
for i := 0; i < 10; i++
fmt.Println(
pos(i),
neg(-2*i),
)
以上是关于Go语言基础的主要内容,如果未能解决你的问题,请参考以下文章