Go语言学习笔记(五)-其他类型(指针、结构体、、)

指针

在Go语言中也存在指针,且指针保存了变量的地址,初始值为nil。定义指针与定义变量相似,不同的是在类型前面指针需要加*例如:

var p *int   //此处定义了一个int类型的指针

指针也可以通过已有变量获取,通过&操作符便可,与C语言相似Go中*指针名指向变量底层,但是不同的是Go中没有指针运算。示例代码如下:

package main
import "fmt"
func main(){
    i,j := 10,1000
    var p *int //定义一个int指针
    p = &i  //从i变量中获取指向i的指针并赋值给p
    fmt.Println(i)
    *p = 21  //修改p指针指向的底层存储的数据
    fmt.Println(i)
    p = &j
    *p = *p/10
    fmt.Println(j)
}

结构体

结构体就是一些字段的集合,通过type来声明定义类型,并用struct来声明结构体。具体实现如下:

package main
import "fmt"
type TestType struct{
    x int
    y int
}
func main(){
    p := TestType{1,2}
    fmt.Println(p)
    p.x = 4
    fmt.Println(p)
}

从上述示例代码中可以看出结构体的字段通过点号来访问。
结构体还可以通过指针来访问,若一个结构体指针为p那么我们可以通过(&p).x来调用结构体的字段或者使用隐式间接引用,直接写p.x就可以。结构体文法可以通过直接列出字段的值来新分配一个结构体,也可以通过Name:语法列出部分字段。

数组

类型[n]T表示拥有n个T类型的值得数组。数组的长度是数组的一部分,所以数组不能改变大小。
为了解决这个限制,Go推出了切片这一类型,切片为数组元素提了供动态大小,灵活的视角,比数组更实用。切片通过[]T来定义。切片不存储任何数据,它只是描述了底层数组中的一段,或者我们也可以理解为切片其实相当于对数据中的一段的每一个元素都获取了一个指针对象存放到另一数组中。创建数组与切片的方法如下:

package main
import "fmt"
func main(){
    //创建一个数组并设置初始值Go自动推导类型
    myArray := [10]int{1,2,3,4,5,6,7,8,9,10}
    fmt.Println(myArray)
    //创建一个数组设置初始值
    var myArray1 [5]int = [5]int{6,5,4,3,2}
    fmt.Println(myArray1)
    //创建一个切片初始元素个数为5,默认值为0,预留10个存储空间
    mySlice := make([]int,5,10)
    fmt.Println(mySlice)
    //从数组上直接创建一个切片,初始元素个数与数组相同
    mySlice2 := []int{1,2,3,4,5}
    fmt.Println(mySlice2)
    //穿件一个切片元素个数为6默认值为0
    mySlice3 := make([]int,6)
    fmt.Println(mySlice3)
}

通过make方式来创建的切片也是创建动态数组的方法。
在进行切片时,可以利用它的默认行为来忽略上下界,切片的下界默认为0,上界为该切片的长度。例如:

package main
import "fmt"
func main(){
    var a [10]int = {1,2,3,4,5,6,7,8,9,10}
    fmt.Println(a[0:10])
    fmt.Println(a[:10])
    fmt.Println(a[:10])
    fmt.Println(a[:])
}

以上四个切片是等价的

切片拥有容量与长度两个属性,长度就是包含的元素个数,容量就是从第一个元素开始到底层数组元素的末尾的个数,长度与容量分别用len(s)和cap(s)来获取。切片的零值为nil,nil切片的容量与长度为0,且没有底层数组。
切片可以包含任何类型,包括切片。
切片可以通过append来追加元素,该函数为自建函数,使用方式如下:

package main
import "fmt"
func main(){
    var s []int
    printSlice(s)
    //输出len=0 cap=0 []
    //追加一个元素
    s = append(s,0)
    printSlice(s)
    //输出len=0 cap=0 []
    //追加多个元素
    s = append(s,2,3,4,5)
    printSlice(s)
    //输出len=1 cap=1 [0]
}
func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

上述代码展示了append的两种使用方式,添加一个元素与添加多个元素

映射(map)

映射就是将键映射到值,映射的零值为nil,nil既没有键也不能添加键,make函数会返回给定类型的映射,并将其初始化备用。映射的文法与结构体相似,但是映射必须要有键名。若顶级类型只有一种类型,那么可以在文法元素中忽略。

package main

import "fmt"

type Vertex struct {
    Lat, Long float64
}

var m = map[string]Vertex{
    "Bell Labs": {40.68433, -74.39967},
    "Google":    {37.42202, -122.08408},
}

func main() {
    fmt.Println(m)
    //输出map[Bell Labs:{40.68433 -74.39967} Google:{37.42202 -122.08408}]

    //修改Bell Labs对应的元素
    m["Bell Labs"] = Vertex{2000,-74.39967}
    fmt.Println(m)
    //输出map[Bell Labs:{2000 -74.39967} Google:{37.42202 -122.08408}]
    
    //删除Bell Labs对应的元素
    delete(m,"Bell Labs")
    fmt.Println(m)
    //输出map[Google:{37.42202 -122.08408}]

    //通过双赋值来判断键是否存在
    v, ok := m["Google"]
    fmt.Println("The value:", v, "Google?", ok)
    //输出The value: {37.42202 -122.08408} Google? true
}

range

for循环的range形式可以遍历切片也可以遍历映射,for循环遍历切片时,每次遍历都会返回两个值,一个是元素的下标一个是元素的副本,通过_可以将下标或者值忽略,当只需要下标时可以直接去掉,value部分。

package main

import (
    "golang.org/x/tour/wc"
    "strings"
)

func WordCount(s string) map[string]int {
    res := make(map[string]int)
    strs := strings.Fields(s)
    for _,v:= range strs{
        res[v]++
    }
    return res
}

func main() {
    wc.Test(WordCount)
}

函数值与闭包

Go中函数也是值,也可以作为参数或者返回值。Go函数可以是一个闭包。闭包是一个函数值,它引用了其函数体之外的变量。该函数可以访问并赋予其引用的变量的值,换句话说,该函数被“绑定”在了这些变量上。

package main

import "fmt"

func main() {
    var j int = 5
    //此处创建了一个匿名函数,返回值为函数值,并通过匿名函数后跟()来执行这个匿名函数将返回的函数值赋值给a变量
    a := func()(func()){
        var i int = 10
        return func(){
            fmt.Printf("i,j: %d , %d\n",i,j)
        }
    }()
    a()
    j *= 2
    a()
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • 出处---Go编程语言 欢迎来到 Go 编程语言指南。本指南涵盖了该语言的大部分重要特性 Go 语言的交互式简介,...
    Tuberose阅读 18,399评论 1 46
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,424评论 3 44
  • 原文链接 http://ironxu.com/709 本文是学习 A Tour of Go (中文参考 Go 之旅...
    好刚编程阅读 535评论 0 5
  • 滚动冲突解决 解决EditText换行后,ScrollView跟随滚动的问题重写ScrollView的comput...
    deathswing阅读 399评论 1 0
  • 18.35分的天空。
    曹小阁阅读 164评论 0 0