Go语言入门篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SoftpaseFar/article/details/79305594

(考研结束继续更新!!!)

基础语法:

1.变量定义

func variableZeroValue(){
    var a int //默认值0
    var s string //默认值""
    fmt.Printf("%d %q\n", a, s)
}

func variableInitValue(){
    var s int = 3
    var s string = "abc"
    fmt.Println(a, s)
}
//或者
func variableInitValue(){
    var a, b int = 3, 4 //不赋初值也可以
    var s string = "abc"
    fmt.Println(a, b, s)
}
//不指定类型,会自动辨认类型

//写在一行(不需要指定类型,自动辨认类型)
func variableTypeDeduction(){
    var a, b, c, s = 3, 4, true, "Hello" 
    fmt.Println(a, b, c, s)
}
//或者
func variableShorter(){
    a, b, c, s := 3, 4, true, "Hello" 
    b = 5
    //第一次=前边一定要有:
    //后边=前有:相当于新定义变量
    fmt.Println(a, b, c, s)
}

//在函数外部,只能用var定义不能用 “:”
//包变量,没有全局变量这种书法
var a = 3
var s = "Hello"
var t = true
//或者
var (
    a = 3
    s = "Hello"
    t = true
)


2.变量类型
  • bool String
  • (u)int (u)int8 (u)int16 (u)int32 (u)int64 uintptr
  • byte rune(这个相当于其他语言的char,为了应对多国语言)
  • float32 float64 comples64(复数) comples128

①需要回顾下复数看这里:
◆例如 i = 1 的结果在实数范围内就无法表示,必须借助复数。
◆复数: 3 + 4 i
| 3 + 4 i | = 3 2 + 4 2 = 5
i 2 = 1 , i 3 = i , i 4 = 1
e i φ = c o s φ + i s i n φ (泰勒公式部分)
| e i φ | = c o s 2 φ + s i n 2 φ = 1
e 0 = 1 , e i π 2 = i
e i π = 1 => e i π + 1 = 0 ( , 0 / 1 , ) , e i 3 π 2 = i , e i 2 π = 1

//下面看个复数的例子
func euler(){
    c := 3 + 4i//还记得函数里可以用:定义变量吗?3 + 4i会自动识别为复数
    fmt.Println(cmplx.Abs(c))//取模,输出5
}

//再看一个欧拉公式的例子
func euler(){
    fmt.Println(
        cmplx.Exp(1i * math.Pi) + 1//Exp()是e的多少次方,1i是为了让编译器把i识别为复数
        //或者
        cmplx.Pow(math.E, 1i * math.Pi) + 1)//Pow()是指定底数和指数,输出结果为实部0的数复数
}

//这个因为是float的所以存在误差
//可以用Printf指定为%.3f(根据情况自己调节精度),输出结果为实际想要的
//另外python也是这样,输出结果跟Go一样

②强制类型转换(Go只有强制类型转换,没有隐式类型转换):
直接看个例子:

func triangle(){
    //勾股定理,3,4,5
    var a, b int = 3, 4
    var c int
    c = math.Sqrt(a*a + b*b)//错误
    c = int(math.Sqrt(float64(a*a + b*b)))//正确
    fmt.Println(c)
    //Sqrt参数为float64,返回结果为int,输出结果为5
    //问题:float在编程语言中是存在误差的,解决方案?
}
3.常量与枚举

☆常量:
◆const filename = “abc.txt”
◆xonst 数值可以作为各种类型使用
◆const a, b = 3, 4(后面用可以不用抢转,自己当所需类型去使用)

func comsts(){
    //指定类型,不指定类型都可以
    const filename string = "abc.txt"
    const a, b = 3, 4
}

func comsts(){
    const filename = "abc.txt"
    const a, b = 3, 4
    var c int//下面需要强制转换
    c = int(math.Sqrt(float64(a*a + b*b)))
    fmt.Println(filename,c)
}

func comsts(){
    const filename = "abc.txt"
    const a, b = 3, 4
    var c//下面不需要强制转换
    c = int(math.Sqrt(a*a + b*b))
    fmt.Println(filename,c)
}

func comsts(){
    const (
        filename = "abc.txt"
        a, b = 3, 4
    )
    var c//下面不需要强制转换
    c = int(math.Sqrt(a*a + b*b))
    fmt.Println(filename,c)
}

☆枚举

func enums(){
    const (
        cpp = 0
        java = 1
        python = 2
        golang = 3
        javascript = 4
        PHP = 5
    )
    fmt.Println(cpp, java, python, golang, javascript, PHP)
}

//或者
func enums(){
    const (
        cpp = iota//iota可以自增,是个种子
        _
        python
        golang
        javascript
        PHP
    )
    fmt.Println(cpp, _, python, golang, javascript, PHP)
}

//或者
func enums(){
    // b kb mb gb tb pb
    const (
        b = 1 << (10 * iota)
        kb
        mb
        gb
        tb
        pb
    )
    fmt.Println(b, kb, mb, gb, tb, pb)
}
4.条件语句

if语句:

func main(){
    const filename = "abc.txt"
    contents, err := ioutil.ReadFile(filename)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Printf("%s\n", contents)
    }
}

//或者

func main(){
    const filename = "abc.txt"
    if contents, err := ioutil.ReadFile(filename); err != nil{
        fmt.Println(err)
    } else {
        fmt.Printf("%s\n", contents)
    }
    //出了if语句contents是不能访问的

}

switch语句:(switch会自动break,除非使用fallthrough)

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
    }

}

//另外一种switch用法:
func grade(score int) string {
    switch {
        g := ""
        case score < 0 || score > 100:
            panic("Wrong score:" + score)
        case score < 60:
            g = "D"
        case score < 80:
            g = "C"
        case score < 90:
            g = "B"
        case score < 100:
            g = "A"
    }
    return g
}
5.循环语句

for循环,没有while:

sum := 0
for i := 1; i <= 100; i++ {
    sum += i
}
//for的条件里不需要括号
//for的条件里可以省略初始条件,结束条件,递增条件


//下几个例子

//import也可以用()一块包含进来
import (
    "fmt"
    "strconv"
)

//省略初始条件
//把一个数转换成二进制
func convertToBin(v int) string {
    result := ""
    for ; v > 0; v /= 2 {
        lsb := v % 2
        result = strconv.Itoa(lsb) + result//strconv.Itoa转换string
    }
    return result
}

// 省略递增条件
func readFile(filename string) string {
    file, err := os.Open(filename)
    if err != nil {
        panic(err)
    }

    scanner := bufio.NewScanner(file)

    for scanner.Scan() {//相当于while 
        fmt.Println(scanner.Teaxt())
    }
}

//省略所有,死循环
for {
    //TODO,后期并发编程,通信等等会用到
}
6.函数
//返回一个值
func eval(a, b int, op string) int {
    //TODO
}


//返回两个值或者多个值(返回商和余数)
func div(a, b int) (int int) {
    return a / b, a % b
}
//或者
func div(a, b int) (q, r int) {
    q = a / b
    r = a % b
    return
    //另外在idea等IDE环境下,如果使用本函数,会自动生成q,r作为返回值接收,这个可以修改
}

/*********************************************/

//Go定义的变量一定要用到,否则编译器会报错
//,当有两个返回值,而又想用其中一个时
//q, _ = div(13, 3)
//return q | 其他操作 即可

/*********************************************/

//还可用于错误返回
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 "/":
            return a / b, nil
        default:
            return 0, fmt.Errorf(
                "unsupported operator: %s", op)
    }

}

提一下函数式编程:
把上边的eval改写下:

func apply(op func(int, int) int,a, b int) int {
    return op(a, b)
}

//便于理解,加入辅助代码
func apply(op func(int, int) int,a, b int) int {
    p := reflect.ValueOf(op).Pointer()//反射拿到函数指针
    opName := runntime.FuncForPC(p).Name()//间接获取名字
    fmt.Printf("Calling function %s with args " + "(%d, %d)", opName, a, b)
    return op(a, b)
}

可变参数(示例):

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

注: 没有函数重载等等比较花哨的方式

7.指针
var a int = 2
var pa *int = &a
*pa = 3
fmt.Println(a)

★★★(不要害怕,比C简单多了)基本使用跟C、C++一样,但指针不能运算,所以简单
★★★ 如果不使用指针全是值传递

内建容器:

1.数组

◆数组定义

func main() {
    //不赋初值,默认值为0
    var arr1 [5]int
    //使用:时,必须赋初值
    arr2 := [3]int{1, 3, 5}
    //如果需要让编译器自动识别长度
    arr3 := [...]int{2, 4, 6, 8, 10}
    fmt.Println(arr1, arr2, arr3)
    //定义一个为维数组,不赋初值默认为0
    var grid [4][5]int
    fmt.Println(grid)
}

◆数组遍历

//常规做法
for i := 0; i < len(arr3); i++ {
    fmt.Println(arr3[i])
}

/*********************/
/*****推荐使用range****/
/******数组是值传递*****/
/*********************/
//或者
for i := range arr3 {//range可以获取数组下标
    fmt.Println(arr3[i])
}
//或者
for i, v := range arr3 {//同时获取value属性
    fmt.Println(i, v)
}
//或者
for _, v := range arr3 {//同时获取value属性
    fmt.Println(v)//只打印值
}
2.Slice(切片)概念 ★★★★★
    // 官方文档说Slice是一个视图,所以不是值传递
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    s := arr[2:6]//前闭后开 


    //再看一个例子
    func updateSlice(s []int) {
        s[0] = 100
    }

    func main() {
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    fmt.Println("arr[2:6] = ", arr[2:6])
    fmt.Println("arr[:6] = ", arr[:6])
    s1 := arr[2:]
    fmt.Println("s1 = ", s1)
    s2 := arr[:]
    fmt.Println("s2 = ", s2)

    fmt.Println("After updateSlice(s1)")
    updateSlice(s1)
    fmt.Println(s1)
    fmt.Println(arr)
    }

运算结果

思考一个问题:

arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
arr[0], arr[2] = 0, 2
s1 = arr[2:6]
s2 = s1[3:5]
//请问s1, s2分别是?

Slice底层实现

Slice结构

fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))
fmt.Printf("s2=%v, len(s2)=%d, cap(s2)=%d\n", s2, len(s2), cap(s2))

切片可以向后扩展,不可以向前!

3.切片的操作

猜你喜欢

转载自blog.csdn.net/SoftpaseFar/article/details/79305594