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)的更多相关文章
- Go:学习笔记兼吐槽(2)
Go:学习笔记兼吐槽(1) Go:学习笔记兼吐槽(2) Go:学习笔记兼吐槽(3) 基本数据类型和string之间的转换 (1) 基本类型转string 使用 fmt.Sprintf(“%参数”, 表 ...
- Go:学习笔记兼吐槽(1)
Go:学习笔记兼吐槽(1) Go:学习笔记兼吐槽(2) Go:学习笔记兼吐槽(3) 自动添加分号 在很多其他的编程语言中,每一行代码的结尾都必须有分号(假设一行中只有一句代码),Golang 的开 ...
- Salesforce学习笔记之吐槽
迄今感到的几个不方便 1. SOQL里没有SELECT * ,只好根据参考手册和用vs code的一个插件Schema Explorer来辅助生成SELECT语句. 2. SOQL不支持注释,Deve ...
- R语言学习笔记之: 论如何正确把EXCEL文件喂给R处理
博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html ---- 前言: 应用背景兼吐槽 继续延续之前每个月至少一次更新博客,归纳总结学习心得好习惯. ...
- Android学习笔记之短信验证码的获取和读取
PS:最近很多事情都拖拖拉拉的..都什么办事效率啊!!! 还得吐槽一下移动运营商,验证码超过五次的时候,直接把我的手机号封闭.真是受够了. 学习笔记: 1.Android之如何获取短信验证码. 2.如 ...
- 【Stage3D学习笔记续】真正的3D世界(一):透视矩阵
如果各位看官跟着我的学习笔记一路看过来的话,一定会吐槽我的,这都是什么3D啊?从头到尾整个都是在使用GPU绘制一堆2D图像而已,的确,之前我们一直使用正交矩阵利用GPU加速来实现2D世界的展示,算不上 ...
- Web Service学习笔记(webservice、soap、wsdl、jws详细分析)
Web Service概述 Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API ...
- Web Service学习笔记
Web Service概述 Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API ...
- Web Service学习笔记(webservice、soap、wsdl、jws详细分析) (转)
Web Service概述 Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API ...
随机推荐
- C++ 文件流的详解
部分内容转载:http://blog.csdn.net/kingstar158/article/details/6859379 感谢追求执着,原本想自己写,却发现了这么明白的文章. C++文件流操作是 ...
- Maven项目管理工具
Maven项目管理工具 白面郎君 Svn eclipse maven量级 1 Maven的简介 1.1 什么是maven 是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目 ...
- Scrapy爬虫框架第三讲(linux环境)
下面我们来学习下Spider的具体使用: 我们已上节的百度阅读爬虫为例来进行分析: 1 # -*- coding: utf-8 -*- 2 import scrapy 3 from scrapy.li ...
- Python3实现ICMP远控后门(中)之“嗅探”黑科技
ICMP后门 前言 第一篇:Python3实现ICMP远控后门(上) 第二篇:Python3实现ICMP远控后门(上)_补充篇 在上两篇文章中,详细讲解了ICMP协议,同时实现了一个具备完整功能的pi ...
- capwap学习笔记——初识capwap(二)(转)
2.5.1 AC发现机制 WTP使用AC发现机制来得知哪些AC是可用的,决定最佳的AC来建立CAPWAP连接. WTP的发现过程是可选的.如果在WTP上静态配置了AC,那么WTP并不需要完成AC的发现 ...
- linux线程及互斥锁
进程是资源管理的最小单元,线程是程序执行的最小单元.在操作系统的设计上,从进程演化出线程,最主要的目的就是更好的支持SMP以及减小(进程/线程)上下文切换开销. 就像进程有一个PID一样,每个线程也有 ...
- subline常用快捷键
一次创建5个class为main的div : div.main*5 +TAB 快速生成HTML结构: ! + TAB 使盒子内的文本水平垂直方向对齐: height:value; line-h ...
- struts2(三)---struts2中的服务端数据验证框架validate
struts2为我们提供了一个很好的数据验证框架–validate,该框架可以很方便的实现服务端的数据验证. ActionSupport类提供了一个validate()方法,当我们需要在某一个acti ...
- java之集合Collection详解之2
package cn.itcast_02; import java.util.ArrayList; import java.util.Collection; /* * 练习:用集合存储5个学生对象,并 ...
- bzoj 3195 奇怪的道路 状压dp
看范围,状压没毛病 但是如果随便连的话给开1<<16,乘上n,m就爆了 所以规定转移时只向回连边 于是想状态数组:f[i][j]表示到i这里i前K位的状态为j(表示奇偶) 发现有条数限制, ...