Go语言基础(九)—— Go语言结构体、Go语言切片(Slice)、range遍历、Go语言Map(集合)

Go语言结构体

Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。 
结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性:

  • Title :标题 
  •  Author : 作者 
  •  Subject:学科 
  •  ID:书籍 ID 

定义结构体

 
 结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体有中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:

type struct_variable_type struct { 
   member definition; 
   member definition; 
   ... 
   member definition; 
}

一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:

variable_name := structure_variable_type {value1, value2...valuen} 

 访问结构体成员

如果要访问结构体成员,需要使用点号 (.) 操作符,格式为:"结构体.成员名"。 结构体类型变量使用 struct 关键字定义,实例如下:

 

package main 
 
import "fmt" 
type Books struct { 
   title string 
   author string 
   subject string 
   book_id int 
} 
 
func main() {   
     var Book1 Books        /* 声明 Book1 为 Books 类型 */   
     var Book2 Books        /* 声明 Book2 为 Books 类型 */ 
 
   /* book 1 描述 */  
     Book1.title = "Go 语言"   
     Book1.author = "wek "   
     Book1.subject = "Go 语言教程" 
     Book1.book_id = 6495407 
 
   /* book 2 描述 */   
     Book2.title = "Python 教程"  
     Book2.author = "wek"    
     Book2.subject = "Python 语言教程" 
     Book2.book_id = 6495700 
 
   /* 打印 Book1 信息 */ 
   fmt.Printf( "Book 1 title : %s\n", Book1.title) 
   fmt.Printf( "Book 1 author : %s\n", Book1.author) 
   fmt.Printf( "Book 1 subject : %s\n", Book1.subject) 
   fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id) 
 
   /* 打印 Book2 信息 */ 
   fmt.Printf( "Book 2 title : %s\n", Book2.title) 
   fmt.Printf( "Book 2 author : %s\n", Book2.author) 
   fmt.Printf( "Book 2 subject : %s\n", Book2.subject) 
   fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id) 
}

结果为:

Book 1 title : Go 语言 
Book 1 author : wek 
Book 1 subject : Go 语言教程 
Book 1 book_id : 6495407 
Book 2 title : Python 教程 
Book 2 author : wek 
Book 2 subject : Python 语言教程 
Book 2 book_id : 6495700 

结构体作为函数参数

你可以像其他数据类型一样将结构体类型作为参数传递给函数。

结构体指针

你可以定义指向结构体的指针类似于其他指针变量,格式如下:

var struct_pointer *Books

以上定义的指针变量可以存储结构体变量的地址。查看结构体变量地址,可以将 & 符号放置
于结构体变量前: 

struct_pointer = &Book1; 

使用结构体指针访问结构体成员,使用 "." 操作符: 

struct_pointer.title; 

Go语言切片(Slice)

切片是 Go 语言中的关键数据类型,为序列提供了比数组更强大的接口。与数组不同,切片(slice)只是由它们包含的元素(而不是元素的数量)键入。要创建 非零长度的空切片,请使用内置 make()函数。 我们可以像数组一样设置和获取字符串的子串值。len()函数返回切片的长度。 除了这些基本操作之外,切片还支持更多,使它们比数组更丰富。一个是内 置 append()函数,它返回包含一个或多个新值的切片。注意,需要接收 append()函数的返回值,因为可能得到一个新的 slice 值。 也可以复制切片。这里创建一个与切片 s 相同长度的空切片 c,并从切片 s 复制到 c 中。切片支持具有语法为 slice[low:high]的切片运算符。 例如,这获得元素 s[2],s[3]和 s[4]的切片。 这切片到(但不包括)s[5]。这切片从(包括)s[2]。可以在一行中声明并初始化slice 的变量。 切片可以组成多维数据结构。内切片的长度可以变化,与多维数组不同。 

定义切片

var identifier []type 

切片不需要说明长度。 或使用 make()函数来创建切片:

var slice1 []type = make([]type, len) 
 
也可以简写为 
 
slice1 := make([]type, len) 

 也可以指定容量,其中 capacity 为可选参数。

make([]T, length, capacity)

这里 len 是数组的长度并且也是切片的初始长度。

切片初始化

直接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是 1,2,3.其 cap=len=3 

s :=[] int {1,2,3 }

初始化切片s,是数组arr的引用

s := arr[:] 

将 arr 中从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片 

s := arr[startIndex:]

缺省 endIndex 时将表示一直到 arr 的最后一个元素 

s := arr[:endIndex] 

缺省 startIndex 时将表示从 arr 的第一个元素开始

s1 := s[startIndex:endIndex]

通过切片 s 初始化切片 s1

s :=make([]int,len,cap) 

通过内置函数 make()初始化切片 s,[]int 标识为其元素类型为 int 的切片

Len()和cap()函数

切片是可索引的,并且可以由 len() 方法获取长度。 切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。

空切片(nil)

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

package main 
 
import "fmt" 
 
func main() { 
   var numbers []int 
 
   printSlice(numbers) 
 
   if(numbers == nil){       fmt.Printf("切片是空的") 
   } 
} 
 
func printSlice(x []int){ 
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x) 
}

结果为:

len=0 cap=0 slice=[] 切片是空的 

append()和copy()函数

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。 下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。

package main 
 
import "fmt" 
 
func main() { 
   var numbers []int 
   printSlice(numbers) 
 
   /* 允许追加空切片 */ 
   numbers = append(numbers, 0) 
   printSlice(numbers) 
 
   /* 向切片添加一个元素 */ 
   numbers = append(numbers, 1) 
   printSlice(numbers) 
 
   /* 同时添加多个元素 */ 
   numbers = append(numbers, 2,3,4) 
   printSlice(numbers) 
 
   /* 创建切片 numbers1 是之前切片的两倍容量*/ 
   numbers1 := make([]int, len(numbers), (cap(numbers))*2) 
 
   /* 拷贝 numbers 的内容到 numbers1 */ 
   copy(numbers1,numbers) 
   printSlice(numbers1)    
} 
 
func printSlice(x []int){ 
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x) 
} 

结果为:

len=0 cap=0 slice=[] 
len=1 cap=1 slice=[0] 
len=2 cap=2 slice=[0 1] 
len=5 cap=6 slice=[0 1 2 3 4] 
len=5 cap=12 slice=[0 1 2 3 4] 

Go语言范围(Range)

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合
(map)的元素。在数组和切片中它返回元素的索引值,在集合中返回 key-value 对的 key 值。

Go语言基础(九)—— Go语言结构体、Go语言切片(Slice)、range遍历、Go语言Map(集合)_第1张图片

package main 
import "fmt" 
func main() {     //这是我们使用 range 去求一个 slice 的和。使用数组跟这个很类似 
    nums := []int{2, 3, 4} 
    sum := 0 
    for _, num := range nums { 
        sum += num 
    } 
    fmt.Println("sum:", sum)     //在数组上使用 range 将传入 index 和值两个变量。上面那个例子我们不需要使用该元素的序号, 所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。 
    for i, num := range nums { 
        if num == 3 { 
            fmt.Println("index:", i) 
        } 
    }     //range 也可以用在 map 的键值对上。 
    kvs := map[string]string{"a": "apple", "b": "banana"} 
    for k, v := range kvs { 
        fmt.Printf("%s -> %s\n", k, v) 
}  //range 可以只迭代 map 的 key 值 
  for k := range kvs { 
        fmt.Println("key:", k) 
} 
 
    //range 也可以用来枚举 Unicode 字符串。第一个参数是字符的索引,第二个是字符(Unicode 的 值)本身。 
    for i, c := range "go" { 
        fmt.Println(i, c) 
    } 
}

结果为:

sum: 9 
index: 1 
a -> apple 
b -> banana 
key: a 
key: b 
0 103 
1 111

Go语言Map(集合)

Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似
于索引,指向数据的值。 Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。

定义Map

可以使用内建函数 make 也可以使用 map 关键字来定义 Map: 

/* 声明变量,默认 map 是 nil */ 
var map_variable map[key_data_type]value_data_type 
 
/* 使用 make 函数 */ 
map_variable := make(map[key_data_type]value_data_type) 

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对

package main 
 
import "fmt" 
 
func main() { 
   var countryCapitalMap map[string]string    /* 创建集合 */ 
   countryCapitalMap = make(map[string]string) 
       /* map 插入 key-value 对,各个国家对应的首都 */ 
   countryCapitalMap["France"] = "Paris" 
   countryCapitalMap["Italy"] = "Rome" 
   countryCapitalMap["Japan"] = "Tokyo" 
   countryCapitalMap["India"] = "New Delhi" 
       /* 使用 key 输出 map 值 */ 
   for country := range countryCapitalMap { 
      fmt.Println("Capital of",country,"is",countryCapitalMap[country]) 
   } 
       /* 查看元素在集合中是否存在 */ 
   captial, ok := countryCapitalMap["United States"]    /* 如果 ok 是 true, 则存在,否则不存在 */ 
   if(ok){ 
      fmt.Println("Capital of United States is", captial)   
   }else { 
      fmt.Println("Capital of United States is not present")  
   } 
}

结果为:

Capital of France is Paris 
Capital of Italy is Rome 
Capital of Japan is Tokyo 
Capital of India is New Delhi 
Capital of United States is not present

delete()函数

delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。实例如下:

 

package main 
 
import "fmt" 
 
func main() {       /* 创建 map */ 
   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":
"Tokyo","India":"New Delhi"} 
       fmt.Println("原始 map")    
       /* 打印 map */ 
   for country := range countryCapitalMap { 
      fmt.Println("Capital of",country,"is",countryCapitalMap[country]) 
   } 
       /* 删除元素 */ 
   delete(countryCapitalMap,"France"); 
   fmt.Println("Entry for France is deleted")   
       fmt.Println("删除元素后 map")    
    

   /* 打印 map */ 
   for country := range countryCapitalMap { 
      fmt.Println("Capital of",country,"is",countryCapitalMap[country]) 
   } 
} 
原始 map 
Capital of France is Paris 
Capital of Italy is Rome 
Capital of Japan is Tokyo 
Capital of India is New Delhi 
Entry for France is deleted 删除元素后 map 
Capital of Italy is Rome 
Capital of Japan is Tokyo 
Capital of India is New Delhi 

 

你可能感兴趣的:(Go语言基础)