Go基础语法-3 | 青训营笔记

85 阅读6分钟

Go基础语法-3 | 青训营笔记

Go 语言的设计目的是作为 C/C++ 的替代工具,是谷歌内部为了解决 C/C++ 开发中的一些痛点:编译慢、不受控制的依赖、三方库混乱、编程范式繁多(每个人都选择其中一部分特性)、并发编程麻烦、跨平台代码兼容、内存安全、工程开发效率低等等。

目录

  • <函数>
  • <结构体>
  • <切片>
  • <集合>

Go函数

入口函数:main()

函数定义如下:

  func function_name( [parameter list] ) [return_types] {
     函数体
  }

调用与c类似,多了值传递或者引用传递,或者传递指针变量

可以方便的返回多个值,和Python类似

函数闭包

每调用一个函数,调用出的函数内的变量初始化一次,相当于每个函数分别独立封闭;

  package main
  
  import "fmt"
  
  func getSequence() func() int {
      i := 0
      return func() int {
          i += 1
          return i
      }
  }
  func main() {
      // nextNumber 为一个函数,函数 i 为 0 
      nextNumber := getSequence()
      // 调用 nextNumber 函数,i 变量自增 1 并返回 
      fmt.Print(nextNumber())
      fmt.Print(nextNumber())
      // 创建新的函数 nextNumber1,并查看结果 
      nextNumber1 := getSequence()
      fmt.Print(nextNumber1())
      fmt.Print(nextNumber())
  }
  
  //运行结果:1213

函数变量

Go中函数可以直接作为变量使用

方法函数

  func (variable_name variable_data_type) function_name() [return_type]{
      //函数体
   }
  package main
  
  import (
      "fmt"
  )
  
  type Circle struct {
      radius float64
  }
  func main() {
      var c1 Circle
      c1.radius = 10.00
      fmt.Println("圆的面积 = ", c1.getArea())
  }
  
  func (c Circle) getArea() float64 {
      return 3.14 * c.radius * c.radius
  }

结构体

声明结构体

 结构体定义需要使用 typestruct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
  type struct_variable_type struct {
     member definition
     member definition
     ...
     member definition
  }
  variable_name := structure_variable_type {value1, value2...valuen}//必须按定义顺序
  variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}

访问结构体成员

如果要访问结构体成员,需要使用点号 . 操作符,格式为:

  结构体.成员名

注意没有->操作符,使用结构体指针访问结构体成员,同样使用 . 操作符

结构体更加类似于java中的类型,而非结构体。

 package main
 
 import "fmt"
 
 type Books struct {
     title   string
     author  string
     book_id int
 }
 
 func main() {
     var Book1 Books
     var Book2 Books
     Book1.title = "homo青春修炼手册"
     Book1.author = "哼哼哼啊啊啊啊啊啊"
     Book1.book_id = 114514
     Book2.title = "6"
     Book2.author = "feellmoose"
     Book2.book_id = 666666
     printBook(&Book1)
     printBook(&Book2)
 }
 
 func printBook(book *Books) {
     fmt.Printf("Book title : %s\n", book.title)
     fmt.Printf("Book author : %s\n", book.author)
     fmt.Printf("Book book_id : %d\n", book.book_id)
 }

Slices(切片)

使用Go切片

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

Go语言中,数组和切片有以下区别:

  1. Go 语言切片是对数组的抽象,功能更加强大;
  2. 切片是指针类型,数组是值类型;
  3. 数组的长度是固定的,而切片不是(切片可以看成动态的数组);
  4. 切片比数组多一个容量(cap)属性;
  5. 切片的底层是数组切片是引用类型,因此在当传递切片时将引用同一指针,修改值将会影响其他的对象当切片和数组作为参数在函数中传递时。数组传递的是值,而切片传递的是指针切片基于数组,但提供了更高的灵活性,可以使用范围来截取切片

切片有着比数组更加广泛的用途,优点:

  1. 可以用来实现动态数组;
  2. 引用传递,可以直接改变原值,在容量过大时避免了值传递的开销

定义切片

  1. 声明一个未指定大小的数组来定义切片
 var identifier []type
  1. 使用 make() 函数来创建切片( make()函数是go语言的一个内置函数。只用于channel,map和slice的创建 )
 var slice1 []type = make([]type, len)
 slice1 := make([]type, len)//不需要添加len

具体方法如下:

 make([]T, length, capacity)

空(nil)切片

一个切片在未初始化之前默认为 nil,长度为 0

初始化切片

  1. 直接初始化切片, [] 表示是切片类型,其 cap=len
 s :=[] int {1,2,3} 
  1. 通过数组初始化,将数组中从下标 第一个下标 到 第二个小标的前一个 元素创建为一个新的切片,可以省略前后任意一个或者两个参数
 s := arr[startIndex:endIndex] 
  1. 通过切片初始化,将切片中从下标 第一个下标 到 第二个小标的前一个 元素创建为一个新的切片
 s1 := s[startIndex:endIndex] 
  1. 通过内置函数 make() 初始化切片s[]int 标识为其元素类型为 int 的切片。
 s :=make([]int,len,cap) 

append() 和 copy() 函数

增加切片容量:如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。


Map(集合)

Map 是一种无序的键值对的集合,可以通过 key 来快速检索数据,key 类似于索引,指向数据的值

在Go中我们可以像迭代数组和切片那样迭代它。遍历 Map 时返回的键值对的顺序是不确定的

在获取 Map 的值时,如果键不存在,返回该类型的零值,例如 int 类型的零值是 0,string 类型的零值是 ""。

Map 是引用类型,如果将一个 Map 传递给一个函数或赋值给另一个变量,它们都指向同一个底层数据结构,因此对 Map 的修改会影响到所有引用它的变量。

定义集合

  1. 使用内建函数 make 或使用 map 关键字来定义 Map
 // 使用 make 函数
 map_variable := make(map[KeyType]ValueType, initialCapacity)
其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。Map 的容量是指 Map 中可以保存的键值对的数量,当 Map 中的键值对数量达到容量时,Map 会自动扩容。如果不指定 initialCapacity,Go 语言会根据实际情况选择一个合适的值。
  1. 使用字面量直接定义并初始化 Map:
 // 使用字面量创建 Map
 m := map[string]int{
     "apple": 1,
     "banana": 2,
     "orange": 3,
 }

使用集合

  1. 获取元素:
  // 获取键值对
  v1 := m["apple"]
  v2, ok := m["pear"]  // 如果键不存在,ok 的值为 false,v2 的值为该类型的零值
  1. 修改元素:
  // 修改键值对
  m["apple"] = 5
  1. 获取 Map 的长度:
  // 获取 Map 的长度
  len := len(m)
  1. 遍历 Map:
  // 遍历 Map
  for k, v := range m {
      fmt.Printf("key=%s, value=%d\n", k, v)
  }
  1. 删除元素:
  // 删除键值对
  delete(m, "banana")