[GO]Golang的一些特有基础语法

1.下划线

下划线的作用是用来接收一个变量,并且不对其进行操作.

比如os.Open,返回值为*os.File,error.

普通写法:

f,err := os.Open("xxxxxxx") 

如果此时不需要知道返回的错误值 就可以用

f, _ := os.Open("xxxxxx") 

如此则忽略了error变量.这样编译器可以更好的优化,任何类型的单个值都可以丢给下划线。

2.变量声明的形式

Go语言的变量声明格式为:

var 变量名 变量类型

Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil

可以在声明的时候同时进行初始化:

var 变量名 类型 = 表达式

 有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。

var 变量名 = 表达式

 在函数内部,可以使用更简略的 := 方式声明并初始化变量。这种:=声明方式不能用于函数外.

func main() {
    n := 10  //短声明方式
    m := 200 
    fmt.Println(m, n)
}

 匿名变量:在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量,用一个下划线_表示,匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。

func foo() (int, string) {
    return 10, "test"
}
func main() {
    x, _ := foo()
    _, y := foo()
    fmt.Println("x=", x)
    fmt.Println("y=", y)
}

 3.Golang的字符,字符串和切片

  Golang的字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。

要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。

 func changeString() {
        s1 := "hello"
        // 强制类型转换 转为切片byteS1
        byteS1 := []byte(s1)
        byteS1[0] = 'H'
        fmt.Println(string(byteS1))
     //rune 类型是一种特殊的int32 用于处理中文等情况 
        s2 := "博客"
        runeS2 := []rune(s2)
        runeS2[0] = '波'
        fmt.Println(string(runeS2))
    }

 4.Golang的数组

1.数组:是同一种数据类型的固定长度的序列。

2.数组定义:var a [len]int,比如:var a [5]int,数组长度必须是常量,且是类型的组成部分。一旦定义,长度不能变。

3.长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型。

4.数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1

 for i := 0; i < len(a); i++ {
    }
    for index, v := range a {
    }

5.访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic

6.数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。

7.支持 "=="、"!=" 操作符,因为内存总是被初始化过的。

8.指针数组 [n]*T,数组指针 *[n]T。

数组初始化的几种方式

    var arr0 [5]int = [5]int{1, 2, 3}
    var arr1 = [5]int{1, 2, 3, 4, 5}
    var arr2 = [...]int{1, 2, 3, 4, 5, 6}
    var str = [5]string{3: "hello world", 4: "tom"}

    a := [3]int{1, 2}           // 未初始化元素值为 0。
    b := [...]int{1, 2, 3, 4}   // 通过初始化值确定数组长度。
    c := [5]int{2: 100, 4: 200} // 使用索引号初始化元素。
    d := [...]struct {
        name string
        age  uint8
    }{
        {"user1", 10}, // 可省略元素类型。
        {"user2", 20}, // 别忘了最后一行的逗号。
    }
  var arr0 [5][3]int
  var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
  a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
  b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."。

 5.Golang的切片

slice 并不是数组或数组指针。它通过内部指针和相关属性引用数组片段,以实现变长方案。

1.切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。

2.切片的长度可以改变,因此,切片是一个可变的数组。

3.切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。

4.cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。

5.切片的定义:var 变量名 []类型,比如 var str []string或var arr []int。

6.如果 slice == nil,那么 len、cap 结果都等于 0。

切片的声明形式:

func main() {
   //1.声明切片
   var s1 []int
   if s1 == nil {
      fmt.Println("是空")
   } else {
      fmt.Println("不是空")
   }
   // 2.:=
   s2 := []int{}
   // 3.make()
   var s3 []int = make([]int, 0)
   fmt.Println(s1, s2, s3)
   // 4.初始化赋值
   var s4 []int = make([]int, 0, 0)
   fmt.Println(s4)
   s5 := []int{1, 2, 3}
   fmt.Println(s5)
   // 5.从数组切片
   arr := [5]int{1, 2, 3, 4, 5}
   var s6 []int
   // 前包后不包
   s6 = arr[1:4]
   fmt.Println(s6)
}

 使用 make 动态创建slice,避免了数组必须用常量做长度的麻烦。还可用指针直接访问底层数组,退化成普通数组操作。通过make创建切片:

    var slice []type = make([]type, len)
    slice  := make([]type, len)  //省略cap,相当于len=cap
    slice  := make([]type, len, cap)

 注意,这时对切片进行操作等于对底层数组进行操作.

6.Golang的字符数组

string底层就是一个byte的数组,因此,也可以进行切片操作。

package main

import (
    "fmt"
)

func main() {
    str := "hello world"
    s1 := str[0:5]
    fmt.Println(s1)

    s2 := str[6:]
    fmt.Println(s2)
}
// 输出结果
// hello
// world

 

posted @ 2021-10-16 17:02  梦想是能睡八小时的猪  阅读(132)  评论(0)    收藏  举报