Go:学习笔记兼吐槽(1)

Go:学习笔记兼吐槽(2)

Go:学习笔记兼吐槽(3)


数组

Golang 中,数组是值类型。

数组的声明

var arr [10]int

数组的初始化

var arr1 [3]int = [3]int{1, 2, 3}
var arr2 = [3]int{4, 5, 6}
var arr3 = [...]int{7, 8, 9}
var arr4 = [...]int{1: 100, 2: 200, 3: 300}

用 for-range 遍历数组

基本语法:

for index, value := range 数组变量{
}

其中:index 为数组下标,value 是该下标位置的值。

长度是数组类型的一部分

长度是数组类型的一部分,就是说数组不可以脱离长度而存在。听起来不太明白,我们来看下面的一个示例就明白了,这真的是一个大坑。

假设,我们现在要写一个排序函数,C# 中,我们会这样定义:

public void Sort(int[] array)
{
}

但是,在 Golang 中,这是不行的。

func main() {
    var arr [3]int = [3]int{1, 2, 3}
    Sort(arr)
} func Sort(array []int){
}

Sort(arr) 这句编译就会报错:cannot use arr (type [3]int) as type []int in argument to Sort。因为 Sort 函数的参数 array []int 是一个切片,不是数组,将数组作为参数传给 Sort 就会报类型不匹配。

如果一定需要以数组作为参数传递,Sort 的参数必须定义成数组,就是带上长度:

func Sort(array [3]int){
}

这么定义这函数还有啥用?吐槽一万字…
虽然有切片可以用来实现我们的功能,但是,数组就变得有点鸡肋了。

切片 slice

切片是引用类型,类似于 C# 中的 list 。内部维护一个数组,当追加元素超出切片容量时,切片自动扩容。(跟 list 是一样的机制。)

切片的声明

var arr []int

切片的使用

//方法一:
var arr1 [5]int = [5]int{1, 2, 3, 4, 5}
slice1 := arr1[1: 3]    //这里的使用跟 Python 很像 //方法二:
var slice2 []int = make([]int, 5, 10) //方法三:
var slice3 []int = []int{1, 2, 3, 4, 5}

使用 make 初始化切片,make 的三个参数依次为:切片数据类型,切片长度,切片容量。

给切片追加元素

//方法一:追加一个或多个同类型
var slice1 []int = make([]int, 5, 10)
slice1 = append(slice1, 100, 200)
fmt.Printf("%v\n", slice1) //方法二:追加切片(只能是切片,不可以是数组)
var slice2 []int = []int{1, 2, 3, 4, 5}
slice1 = append(slice1, slice2...)    // 三个点不能少
fmt.Printf("%v", slice1)

append 函数也很搞笑,其返回值必须赋值给一个切片,否则编译都过不了。如果一个切片调用 append 追加元素后,又赋值给了自己(我们一般也是这么用的),则切片的地址不会发生改变(除非发生了扩容)。如果 切片 1 调用 append 后赋值给了 切片 2,则 切片 1 保持未追加前的原样不变,另生成一个新的切片赋给 切片 2

示例:

var slice1 []int = make([]int, 5, 10)
fmt.Printf("%v %p\n", slice1, &slice1)    // [0 0 0 0 0] 0xc000004460 slice1 = append(slice1, 100)
fmt.Printf("%v %p\n", slice1, &slice1)    // [0 0 0 0 0 100] 0xc000004460 slice2 := append(slice1, 200)
fmt.Printf("%v %p\n", slice1, &slice1)    // [0 0 0 0 0 100] 0xc000004460
fmt.Printf("%v %p\n", slice2, &slice2)    // [0 0 0 0 0 100 200] 0xc0000044e0

映射 map

就是字典。

map 的声明

var m map[int]string

map 的使用

// 方式一:使用 make 函数
m := make(map[int]string, 10) // 方式二:直接赋值
m := map[int]string{
    1: "张三",
    2: "李四",
}

make 方法的第一个参数是 map 的数据类型,第二个参数是初始容量。

注意,如果是方式二直接赋值,最后一个 key-value 后面也要加逗号。

删除元素

delete(map, key)

参数:

  • map:要删除元素的 map
  • key:要删除的 key,当 key 在 map 中不存在时,不进行任何操作,也不报错。

Golang 中 map 没有类似其他语言中的 clear 方法,如果要一次性删除全部元素,可遍历 map 逐一删除,或者重新 make 一下使其指向一个新的内存空间。

查找元素

val, finded := m[1]
if finded{
    fmt.Println(val)
}

遍历元素

只能用 for-range 遍历

for k, v := range m{
    fmt.Printf("%v: %v\n", k, v)
}

结构体 struct

  • Golang 中没有类(class),Go 中的结构体(struct)和其他语言中的类有同等的地位。可以理解为 Golang 是基于 struct 来实现面向对象。
  • 结构体是值类型。结构体的所有字段在内存中是连续的。

结构体的声明

type 结构体名称 struct{
    field1 type
    field2 type
}

结构体的使用

type Person struct{
    Name string
    Age int
} // 方式一:
p1 := Person{}
p1.Name = "Tom"
p1.Age = 10 // 方式二
p2 := Person{"Jerry", 5} // 方式三
p3 := Person{Name: "张三", Age: 30}
// 或
p3 := Person{
Name: "张三", 
Age: 30,        // 注意这里要加逗号,否则会被默认加上分号
}

结构体指针

// 方式一:
var person1 *Person = new(Person)
(*person1).Name = "Tom"
(*person1).Age = 10
fmt.Println(*person1) // 方式二:
person2 := new(Person)
person2.Name = "Tom"
person2.Age = 10
fmt.Println(*person2) // 方式三:
var person3 *Person = &Person{"Jerry", 5}
fmt.Println(*person3)

这三种方式定义的都是结构体指针,因为是指针,所以给字段赋值的标准方式应该是方式一的写法,但是 Go 的设计者为了程序员使用方便,给出了一个语法糖,使 (*person1).Name = "Tom" 简化为 person1.Name = "Tom",即方式二的写法,编译时,会自动加上取值运算。而方式三的写法可以直接赋值。

结构体标签

struct 的每个字段上可以定义一个标签(tag),该标签可以通过反射机制获取,最常见的使用场景就是序列化和反序列化。

type Person struct{
    Name string `json:"name"`
    Age int `json:"age"`
} p := Person{"张三", 30}
jsonStr, err := json.Marshal(p)
if err == nil {
    fmt.Println(string(jsonStr)) // {"name":"张三","age":30}
}

自定义数据类型

为了简化数据类型定义,Golang 支持自定义数据类型。

基本语法:

type 自定义数据类型名 数据类型  // 相当于起了一个别名

示例:

type myint int  //这时 myint 就等价于 int,但是 Go 会认为他们还是两个类型
type mySum func(int, int) int  //这时 mySum 就等价于一个函数类型

自定义数据类型跟原类型虽然在我们的理解上是一样的,但是 Golang 会认为它们是两种不同的数据类型。这导致这两种类型是无法直接进行比较的,必须强转。

Go:学习笔记兼吐槽(3)的更多相关文章

  1. Go:学习笔记兼吐槽(2)

    Go:学习笔记兼吐槽(1) Go:学习笔记兼吐槽(2) Go:学习笔记兼吐槽(3) 基本数据类型和string之间的转换 (1) 基本类型转string 使用 fmt.Sprintf(“%参数”, 表 ...

  2. Go:学习笔记兼吐槽(1)

      Go:学习笔记兼吐槽(1) Go:学习笔记兼吐槽(2) Go:学习笔记兼吐槽(3) 自动添加分号 在很多其他的编程语言中,每一行代码的结尾都必须有分号(假设一行中只有一句代码),Golang 的开 ...

  3. Salesforce学习笔记之吐槽

    迄今感到的几个不方便 1. SOQL里没有SELECT * ,只好根据参考手册和用vs code的一个插件Schema Explorer来辅助生成SELECT语句. 2. SOQL不支持注释,Deve ...

  4. R语言学习笔记之: 论如何正确把EXCEL文件喂给R处理

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html ---- 前言: 应用背景兼吐槽 继续延续之前每个月至少一次更新博客,归纳总结学习心得好习惯. ...

  5. Android学习笔记之短信验证码的获取和读取

    PS:最近很多事情都拖拖拉拉的..都什么办事效率啊!!! 还得吐槽一下移动运营商,验证码超过五次的时候,直接把我的手机号封闭.真是受够了. 学习笔记: 1.Android之如何获取短信验证码. 2.如 ...

  6. 【Stage3D学习笔记续】真正的3D世界(一):透视矩阵

    如果各位看官跟着我的学习笔记一路看过来的话,一定会吐槽我的,这都是什么3D啊?从头到尾整个都是在使用GPU绘制一堆2D图像而已,的确,之前我们一直使用正交矩阵利用GPU加速来实现2D世界的展示,算不上 ...

  7. Web Service学习笔记(webservice、soap、wsdl、jws详细分析)

    Web Service概述 Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API ...

  8. Web Service学习笔记

    Web Service概述 Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API ...

  9. Web Service学习笔记(webservice、soap、wsdl、jws详细分析) (转)

    Web Service概述 Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API ...

随机推荐

  1. python_函数默认参数设计

    >>> def printMax(a,b): if a>b: print(a,'is the max') else: print(b,'is hte max') >> ...

  2. 微信小程序开发入门:10分钟从0开始写一个hello-world

    小程序开发需要三个描述整体程序的app文件 和 一个描述多个页面的 pages文件夹. (1)三个app文件分别是app.js,app.json,app.wxss. app.js文件是脚本文件处理一些 ...

  3. Java 精简Jre jar打包成exe

    #开始 最近几天都在忙一个事情,那就是尝试精简jre,我想不明白为什么甲骨文官方不出exe打包工具... 网络上精简jre的文章很多,但是原创的似乎没几个,绝大多数都是转发同一个博客, 这里借鉴了不少 ...

  4. Scrapy 1.4 文档 04 例子

    最好的学习方法是举例说明,Scrapy也不例外. 因此,我们有一个名为 quotesbot 的 Scrapy 项目,您可以通过它来学习更多关于 Scrapy 的知识. 它包含两个用于http://qu ...

  5. XML解析的四种方法 建议使用demo4j解析 测试可以用

    https://www.cnblogs.com/longqingyang/p/5577937.html 4.DOM4J解析  特征: 1.JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功 ...

  6. CSS+DIV定位分析(relative,absolute,static,fixed)

    在用CSS+DIV进行布局的时候,一直对position的四个属性值relative,absolute,static,fixed分的不是很清楚,以致经常会出现让人很郁闷的结果.今天研究了一下,总算有所 ...

  7. mac下安装Maven和配置环境变量

    1.下载maven包: 下载链接:

  8. UOJ182 a^-1 + b problem 解题报告

    题目描述 有一个长度为\(n(n\le 10^5)\)的数列,在模\(M\)意义下进行\(m(m \le50000)\)次操作,每次操作形如以下两种形式: 1 \(x\) 表示每个数加\(x(0 \l ...

  9. 【小白学C#】谈谈C#多播委托因异常而终止的解决方案

    一.前言 前几天,马三在与朋友闲聊技术的时候,朋友忽然抛出一个问题,把马三难倒了,本着求知的精神,回来以后马三就查阅了相关资料并做了一些实验,终于把问题搞明白了,因此写下本篇博客记录一下.首先,问题是 ...

  10. Linux下全局安装composer

    下载composer curl -sS https://getcomposer.org/installer | php 将composer.phar文件移动到bin目录以便全局使用composer命令 ...