25个关键字

  程序声明:import, package

  程序实体声明和定义:chan, const, func, interface, map, struct, type, var

  程序流程控制:go, select, break, case, continue, default, defer, else, fallthrough, for, goto, if, range, return

类型

  18个基本类型:bool, string, rune, byte, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, float32, float64, complex64, complex128

  7个复合类型:array, struct, function, interface, slice, map, channel

  其中,切片、字典、通道类型都是引用类型

  类型的声明一般以 type 关键字开始,然后是自定义的标识符名称,然后是基本类型的名称或复合类型的定义。

  Unicode字符rune类型是和int32等价的类型,通常用于表示一个Unicode码点。这两个名称可以互换使用。同样byte也是uint8类型的等价类型,byte类型一般用于强调数值是一个原始的数据而不是一个小的整数。

  最后,还有一种无符号的整数类型uintptr,没有指定具体的bit大小但是足以容纳指针。uintptr类型只有在底层编程是才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。

  一个float32类型的浮点数可以提供大约6个十进制数的精度,而float64则可以提供约15个十进制数的精度;通常应该优先使用float64类型,因为float32类型的累计计算误差很容易扩散,并且float32能精确表示的正整数并不是很大

操作符

  列举一些特殊的操作符,注意下面的位操作符

&      位运算 AND
| 位运算 OR
^ 位运算 XOR
&^ 位清空 (AND NOT)
<< 左移
>> 右移

  可以通过 Printf 函数的 %b 参数来输出二进制格式的数字。

特殊的空标识符

  下划线 _ 作为一个特殊的标识符,可以用于 import 语句中,仅执行导入包中的 init 方法。也可以作为赋值语句的左边,表示该变量并不关心且不使用。

  此外,标识符首字母的大小写,在GO语言中被用来控制变量或函数的访问权限,类似于其它语言的 public\private。

类型断言

  比较特殊的表达式有类型断言,如果判断一个表达式 element 的类型是 T 的话,表达式为 element.(T),意思是 element 不为 nil 且存储在其中的值是T类型。这里有两种情况,如果 T 不是一个接口类型,则 element 必须要为接口类型的值,比如判断 100 是 int 型,不能使用 100.(int),而要用 interface{}(100).(int) ; 如果T 是一个接口类型,表示断言 element 实现了 T 这个接口。如果函数的参数是一个空接口,则必须断言传入的接口实现类型,才能使用其对应的方法。

可变参函数

  最后一个参数为 ...T 的形式的函数即为可变参函数,意味着可变参数都是 T 类型(或实现了T的类型)如:func CallFunction(first string, t ...string),GO语言会在调用可变参函数时,创建一个切片,然后将这些可变参数放入切片中,但如果传入的可变参部分就是一个元素类型为T的切片的话,则直接把传入切片赋值给创建的切片,且在调用写法上也有区别,为: CallFunction("hello", []string{"x","y"}...)

数组类型

  array: 声明一个长度为 n 、元素类型为 T 的数组为: [n]T, 元素类型可以为基本类型也可以为复合类型,也可以不指定 n ,由推导得出,如: [...]string{"a","b"} , 数组长度 n = len([...]string{"a","b"}),另外如果指定了数组长度,但定义的数组长度小于声明的长度,则以声明长度为准,不足的元素补默认值。同一元素类型,但数组长度不同,则视为不同类型。

切片类型

  slice: 切片类型的声明为 []T数组,切片类型里没有关于长度的规定,其它跟数组一样,切片类型的零值是 nil。切片总是对应于一个数组,其对应的数组称为底级数组。切片和其底层数组的关系是引用关系,如果有修改都会影响到对方。

  切片的数据结构包含了指向其底层数组的指针、切片长度和切片容量。切片的长度很容易理解,切片的容量是什么呢,它是切片第一个元素到底层数组最后一个元素的长度。

字典类型

  map: 定义一个哈希表的格式为 map[K]V,其中 K 表示键的类型,V表示值的类型,如: map[string]bool{"IsOK":true, "IsError":false}

接口类型

  定义了一组方法声明,接口中可以包含接口

  GO语言对接口类型的实现是非侵入式的(备注:侵入式是指用户代码与框架代码有依赖,而非侵入式则没有依赖,或者说耦合),只要一个类型定义了某个接口中声明的所有方法,就认为它实现了该接口。

  一个特殊的接口: interface{} 是一个空接口,不包含任何方法声明,所以GO语言所有的类型都可以看成是它的实现类型,我们就可以使用它实现类似其它语言中的公共基类的功能。比如声明一个字典,键是字符串,值是不确定类型,就可以使用 map[string]interface{}

  判断一个类型是否实现了一个接口,可以通过类型断言来确定: _, ok := interface{}(MyType{}).(MyInterface)

函数与方法

  GO语言中,函数跟方法是有区别的,函数就是我们通常理解的函数,而方法是附属于某个自定义数据类型的函数,即存在某个接收者。

  func (self MyType) Len() int {}     这里的 (self MyInterface) 是表示方法接收者。

  值方法和指针方法,值方法是指接收者是一个对象,而指针方法是指接收者是一个对象指针。两者的区别是,值方法中对接收者的改变是副本级别的,而指针方法中对接收者的改变是地址级别的。所以其实一般都推荐使用指针方法,因为大多数情况下我们在方法内部修改接收者,都是为了真实的改变它,而不是改变一个副本。但是,对于引用类型的接收者来说,两者并无区别。

  匿名函数由函数字面量表示,函数是作为值存在的,可以赋给函数类型的变量。如:

    var myfunc func(int, int) int
myfunc = func(x, y int) (result int) {
result = x + y
return
}
log.Println(myfunc(, ))

  一个方法的类型是一个函数类型,即把接收者放到函数的第一个参数位置即可。

  非常遗憾,GO语言不支持函数和方法重载。

结构体

  可以包含字段,也可以包含匿名字段,一般匿名字段是接口类型,这样就相当于该结构体包含了该接口中的方法,另外也可以在结构里重写隐藏接口中的方法。

  

指针

  有一个专门用于存储内存地址的类型 unitptr,它与 int/unit 一样属于数值类型,存储32/64位无符号整数。

  可以在一个类型前面使用*号,来表示对应的指针类型,也可以在可寻址的变量前面使用&,来获取其地址。

常量

  定义常量和多个常量如下:

    const PP = iota        //
const QQ = iota // const (
A =
B =
C
D = iota
E
F
)
log.Print(A, B, C, D, E, F)
//输出是: 1 2 2 3 4 5

  注意,iota 只能在 const 里使用,它是 const 的行数索引器,其值是所在const组中的索引值,单常量定义时 iota 就等于 0。另外,const组中某一项如果不赋值,则默认和上一个值一样,但如果前面是 iota ,则为上一个值+1。使用 iota 可以实现其它语言中的枚举。

变量

  变量的声明语句以 var 开始,声明多个变量时,和声明多个const的方法相同。

var x string = "df"
var x = "df"
x := "df" //此为简写形式。

数据初始化

  GO语言的数据初始化有两种方法,一是使用 new ,一是使用 make ,其中 new 是为某个类型分配内存,并设置零值后返回地址,如 new(T) 返回的就是指向T类型值指针值,即*T。如 new([3]int) 其实相当于 [3]int{0,0,0},所以它是一种很干净的内存分配策略。

  make 只用于创建切片类型、字典类型和通道类型(注意这三个类型的特点,都是引用类型),它对这些类型创建之后,还会进行必要的初始化,与 new 不同,它返回的就是指T类型的值,而不是指针值。

定义常量的方式是使用 const ,如 const PI = 3.14,如果定义多个常量可以使用

编译器会自动选择在栈上还是在堆上分配局部变量的存储空间,但可能令人惊讶的是,这个选择并不是由用var还是new声明变量的方式决定的。 如果一个函数里声明一个局部变量,但是将其指针赋给一个全局变量,那么则不能将此局部变量放在栈中,而只能放在堆中,我们可以称之为该局部变量逃逸了,所以关于变量是分配在栈上还是堆上,是由编译器根据情况来选择的。

内建函数

  close 只接受通道类型的值

  len函数,可以应用于字符串、切片、数组、字典、通道类型

  cap函数,可以应用于切片、数组、通道类型

  new函数和make函数

  append函数和copy函数,应用于切片

  delete函数,根据字典的键删除某一项

  complex\real\imag函数,复数相关

  panic 函数,异常相关,它的参数一般是某个error接口的某个实现类型;recover 函数,不接受任何参数,返回 interface{} 类型,也就是意味着,它可以返回任意类型。recover返回的内容是与panic相关的,就是panic的参数内容。

  print\println 函数,这两个函数支持基本类型参数,且是可变参数。但输出格式是固定的,且GO语言不保证以后会保留这两个函数,所以知道就好,不推荐使用。可以使用 fmt.Print 和 fmt.Println 来代替,效果更佳。

合并书写:

和 var/const 类似,多个 type 定义可合并成组,如下:

type (
Person struct {
Name string
Age int32
} myfunc func(string) bool
)

尤其是在函数内部定义一堆临时类型时,可集中书写,可读性更好。

自增/自减运算符不同于其它语言,不能用作表达式,只能当独立的语句使用,且不能前置,只有后置形式,以尽可能避免该运算符带的复杂性问题。

unsafe.Pointer 与 uintptr 的区别:

前者类似 C 语言中的 void* 万能指针,能安全持有对象,但后者不行,后者只是一种特殊整型,并不引用目标对象,无法阻止垃圾回收器回收对象内存。

golang笔记——数据类型的更多相关文章

  1. golang: 常用数据类型底层结构分析

    虽然golang是用C实现的,并且被称为下一代的C语言,但是golang跟C的差别还是很大的.它定义了一套很丰富的数据类型及数据结构,这些类型和结构或者是直接映射为C的数据类型,或者是用C struc ...

  2. 【GoLang】golang底层数据类型实现原理

    虽然golang是用C实现的,并且被称为下一代的C语言,但是golang跟C的差别还是很大的.它定义了一套很丰富的数据类型及数据结构,这些类型和结构或者是直接映射为C的数据类型,或者是用C struc ...

  3. GoLang基础数据类型--->字典(map)详解

    GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...

  4. GoLang基础数据类型-切片(slice)详解

    GoLang基础数据类型-切片(slice)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数组的长度在定义之后无法再次修改:数组是值类型,每次传递都将产生一份副本.显然这种数 ...

  5. GoLang基础数据类型--->数组(array)详解

    GoLang基础数据类型--->数组(array)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Golang数组简介 数组是Go语言编程中最常用的数据结构之一.顾名 ...

  6. GoLang基础数据类型--->字符串处理大全

    GoLang基础数据类型--->字符串处理大全 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入:   高级运维工程师之路               59843264 ...

  7. golang笔记1

    golang笔记1 go代码是用包来组织的,每个包有一个或多个go文件组成,这些go文件文件放在一个文件夹中 每个源文件开始都用一个package声明,指明本源文件属于哪个包 pakage声明后紧跟这 ...

  8. Golang笔记(二)面向对象的设计

    Golang笔记(二)面向对象的设计 Golang本质还是面向过程的语言,但它实现了一些OOP的特性,包括抽象.封装.继承和多态. 抽象和封装 Golang和C语言一样以struct为数据结构核心,不 ...

  9. Golang笔记(一)简洁的语言风格

    Golang笔记(一)简洁的语言风格 概述 Golang继承了很多C语言的风格,寡人使用了十几年C语言,切换到Golang时上手很快,并且随着深入的使用,越来越喜欢这门语言.Golang最直观的感受是 ...

随机推荐

  1. spring-HelloWorld

    准备工作,安装SpringIDE,找到SpringSource-tool-suit,然后按照, 关键的一部在与找到之后该安转那些呢,答案是只安转带有SpringIDE的, 有四个,且不要点击联网进行更 ...

  2. Oracle参数化查询

    Oracle参数化查询默认是根据顺序绑定的 select * from table where name=:p1 and (select id from table2 where name=:p1); ...

  3. Zabbix low-level discovery

    Version: zabbix 3.0.1 概述 Low-Level discovery 可以自动创建items,triggers,graphs为不同的实体对象. 例如:zabbix能自动监控服务器上 ...

  4. Ubuntu 使用笔记

    持续更新 从前使用sudo apt update更新时, 发现软件源是cn.archive.ubuntu.com. 最近在system setting 中将软件源改成了archive.ubuntu.c ...

  5. rpm包安装过程中依赖问题“libc.so.6 is needed by XXX”解决方法

    rpm包安装过程中依赖问题"libc.so.6 is needed by XXX"解决方法 折腾了几天,终于搞定了CentOS上的Canon LBP2900打印机驱动.中间遇到了一 ...

  6. POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)

    传送门 The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8690   Acce ...

  7. OC冒泡排序

    NSMutableArray *p = [[NSMutableArray alloc] initWithObjects:@"3",@"5",@"4&q ...

  8. 数据结构与算法分析 - 网络流入门(Network Flow)

    转载:网络流基础篇--Edmond-Karp算法             BY纳米黑客 网络流的相关定义: 源点:有n个点,有m条有向边,有一个点很特殊,只出不进,叫做源点. 汇点:另一个点也很特殊, ...

  9. linux下git的简单运用

    linux下git的简单运用 windows下也有git,是git公司出的bash,基本上模拟了linux下命令行.许多常用的命令和linux下操作一样.也就是说,windows下的git命令操作和l ...

  10. 给linux添加yum源。

    在玩linux的过程中,经常会下载一些源码包.软件大多是国外人写的,由于众所周知的原因,网络下载很慢. 所以想到了更新yum源的方法. 我的linux版本是CentOS6.3的. 以下参考百度. 1, ...