Go 语言基础语法

1 基础语法

内建变量类型

布尔型

var a bool = true

字符串

var b string = "字符串"

整形

整形 int 按照计算机位数 64 位计算机是 64 位
(u)int、(u)int8、(u)int16、(u)int32、(u)int64
u 代表无符号

var c int = -100000
var d uint8 = 200

指针

var e uintptr

字节

var f byte
var g rune = 0x767d
string(g)

浮点型

var h float32 = 1.111
var i float64 = 2.222

复数

var j complex64 = 3 + 4i
var k complex128 = 6 + 8i
k
(6+8i)

欧拉公式

import "math/cmplx"
import "math"
cmplx.Pow(math.E, 1i * math.Pi) + 1
(0+1.2246467991473515e-16i)

使用 Exp(代表 e 的多少次方)

cmplx.Exp(1i * math.Pi) + 1
(0+1.2246467991473515e-16i)
import "fmt"
fmt.Printf("%.3f", cmplx.Exp(1i * math.Pi) + 1)
(0.000+0.000i)




14 

强制类型转换

没有隐式类型转换

var a, b int = 3, 4
var c int
c = int(math.Sqrt(float64(a * a + b * b)))
c
5

如果算出来是 4.999999 时,使用 int 转换会得到 4 而不是 5

常量

常量的数字类型可以作为各种数字类型使用

const a, b = 3, 4
c = int(math.Sqrt(a * a + b * b))
c
5

枚举类

const(
    a = 1
    b = 2
    c = 3
)

iota 自增

const(
    a = iota // 0
    b        // 1
    c        // 2
    _        // 3 (跳过)
    e        // 4
)
e
4

iota 表达式

const(
    a = 1 << (10 * iota) // 1 * 2 的 0次方
    b                    // 1 * 2 的 10次方
    _                    // 1 * 2 的 20次方
    d                    // 1 * 2 的 30次方
)
b
1024

指针

常量是无法打印出地址的

&c
cannot take the address of a const: c 

一般指针

var a int = 2
var pa *int = &a // *int 指向 int 的指针
*pa = 3
a
3

参数传递-值传递

实际使用可以通过赋值来写,下面只是使用上的演示

func swap(a, b *int) {
    *a, *b = *b, *a
}
a, b := 1, 2
swap(&a, &b)
a
2

写成下面这样的好

func swap(a, b int) (int, int) {
    return b, a
}
a, b = swap(a, b)
a
1

条件语句

If Else

var aa = 1
if aa == 1 {
    aa = 2
} else if aa == 2 {
    aa = 3
}

尝试打开 tset.txt 文件,如果打开出错则打印出错误信息

import "io/ioutil"
import "fmt"
const filename = "test.txt"

contents, err := ioutil.ReadFile(filename)
if err != nil {
    fmt.Println(err)
} else {
    fmt.Printf("%s", contents)
}
open test.txt: no such file or directory

效果相同的合并写法

if contents, err := ioutil.ReadFile(filename); err != nil {
    fmt.Println(err)
} else {
    fmt.Printf("%s", contents)
}
// 需要注意这种写法 contents, err 两个变量的作用域只在 IF 的块中,执行完后就会销毁
open test.txt: no such file or directory

Switch

不需要 break,默认每个 case 都会 break
如果不需要,则需要使用 fallthrough

var bb = 1
switch bb {
    case 0:
        bb = 10
    case 1:
        bb = 20
    default:
        panic("值异常")
}
bb
20

循环

For 循环

sum := 0
for i := 1; i <= 100; i ++ {
    sum += 1
}
sum
100

省略起始条件-转换 int 到二进制

import "strconv"

/*
转换 int 到二进制
*/
func convert2Bin(number int) string {
    result := ""
    // 没有起始条件省略
    for ; number > 0; number /= 2 {
        lsb := number % 2
        result = strconv.Itoa(lsb) + result
    }
    
    return result
}
convert2Bin(222)
11011110

省略递增条件-逐行打印文件内容

import (
    "os";
    "bufio"
)
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())
    }
}
printFile("File/Test/test_print.txt")
apple
juice

省略结束条件-死循环

// for {
//     sum += 1
// }

函数

函数的类型也是在后面定义的

func testFunction(number int) int {
    if number == 1 {
        return 1
    }

    return 0
}
testFunction(1)
1

一般函数-简单的计算函数

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("未知的操作符")
    }
}
eval(1, 1, "+")
2

多个返回参数-分离余数函数

13 / 3 = 4……1

func div(a, b int) (int, int) {
    return a / b, a % b
}
div(13, 3)
4 1

可以像下面一样先定义返回的变量,然后赋值,最后再返回
这样写可以,但是可能会看起来不太方便

func div(a, b int) (q int, r int) {
    q = a / b
    r = a % b
    return
}
a, _ := div(13, 3) // 使用下划线忽略不需要使用的变量
a
4

复合函数

import(
    "reflect";
    "fmt";
    "runtime"
)

func apply(op func(int, int) int, a, b int) int {
    p := reflect.ValueOf(op).Pointer()
    opName := runtime.FuncForPC(p).Name()
    fmt.Printf("调用了函数 %s,参数(%d,%d)", opName, a, b)

    return op(a, b)
}
import "math"

func pow(a, b int) int {
    return int(math.Pow(float64(a), float64(b)))
}
apply(pow, 3, 4)
调用了函数 reflect.makeFuncStub,参数(3,4)




81

匿名函数

上面这样也可以用匿名函数实现

apply(
    func(a, b int) int {
        return int(math.Pow(float64(a), float64(b)))
    },
    3, 4
)
repl.go:5:9: missing ',' before newline in argument list

可变参数

func sum(numbers ...int) int {
    sum := 0
    for i := range numbers {
        sum += numbers[i]
    }

    return sum
}
sum(1, 2, 3, 4, 5)
15

其它

注释

// 单行注释

/*
多行注释 1
多行注释 2
*/

保留关键词

共有 25 个保留关键词

包管理(2个):
import package

程序实体声明与定义(8个):
chan const func interface map struct type var

程序流程控制(15个):
break case continue default defer else fallthrough
for go goto if range return select switch