内容简介:本系列文章并不会关注语法使用层面,更关心可能在使用中会出现的问题、以及通过这些问题引起的一些思考。相信这个系列会成为很有价值的文章。本文只关注Go语言的基本类型:如整型、浮点型、常量相关的内容。字符串、数组和切片等高级类型会在下一篇文章中讲述。初始化顺序:当前包级别变量 -> 导入外部包的init() -> 当前包内的init() -> main()。通常可将一个包导入但是不使用的方式,初始化某些配置数据。
声明
本系列文章并不会关注语法使用层面,更关心可能在使用中会出现的问题、以及通过这些问题引起的一些思考。相信这个系列会成为很有价值的文章。
要点
本文只关注 Go 语言的基本类型:如整型、浮点型、常量相关的内容。字符串、数组和切片等高级类型会在下一篇文章中讲述。
包
初始化顺序:当前包级别变量 -> 导入外部包的init() -> 当前包内的init() -> main()。通常可将一个包导入但是不使用的方式,初始化某些配置数据。
下面这段代码会运行config包和model包下的init()方法:
import (
"cmdb-bg/cmd"
_ "cmdb-bg/config"
_ "cmdb-bg/model"
)
零值
我们都知道,当我们仅仅声明一个变量、但未对其进行初始化的时候,Go会给每种变量类型赋一个零值:
- 整型:0
- 浮点型:0
- bool型:false
func main() {
var a int
var b float64
var c bool
fmt.Println(a, b, c) // 0 0 false
}
赋值与类型推断
如果你之前已经使用了":="对某个变量进行了声明与初始化,如果你想再次为这个变量进行重新赋值,切记不要加":"
func main() {
a := 1
a := 2
fmt.Println(a) // 报错:no new variables on left side of :=
a = 2 // ok
}
func main() {
var a int = 1
for a >= 1 {
a := 2 // 无限循环
a = 2 // 正常执行
a = a-2
fmt.Println(a)
}
}
Go中可以用如下方式高效交换两个变量的值:
func main() {
a := 0
b := 1
a, b = b, a // 交换,不需要使用临时变量
fmt.Println(a, b) // 1, 0
}
- Go的new()返回的是一个地址,而不是值本身:
func main() {
a := new(int)
fmt.Println(a) // 0xc000016050
}
if赋值加判断复合语句的作用域:f的作用域会被限制在if大括号所包裹的代码块内。在if的外部并不能使用变量f:
func f1() error {
if f, err := os.Open("abc"); err != nil {
return err
}
fmt.Println(f) // 编译不通过: undefined: f
}
// 解决:
func f1() error {
f, err := os.Open("abc")
if err != nil {
return err
}
f.Close() // ok
}
运算与类型转换
int和int32是不同类型,若要把int当成int32来使用,必须进行强制类型转换。其他类型同理。
类型断言的使用(暂作了解):
func main() {
// a必须是空接口类型, 任何类型都是interface的实现类,当声明为interface{}时,可以赋值给他任意类型
var a interface{}
a = 2;
// 类型断言会返回两个值
v, ok := a.(int)
// 如果变量a是断言的类型,ok为true,v为被断言变量的值。
// 否则ok为false,v为断言类型的零值
fmt.Println(v, ok) // 2 true
}
如果进行算术运算之后发生了溢出,那么Go会直接丢掉溢出的高位部分。
所有基本类型的值都是可以比较的(整型、浮点型),其他高级类型的比较,一部分需要遵循一定规则,而一部分高级类型是禁止比较的。
不同数据类型不能直接做运算。不像其他语言,Go语言没有隐式类型转换。要想强制对不同类型做运算,必须进行显式的强制类型转换。转换成同一种类型之后,才能做运算:
func main() {
var a int8 = 100
var b int16 = 100
fmt.Println(a + b) // invalid operation: a + b (mismatched types int8 and int16)
fmt.Println(int16(a) + b) // ok
}
在进行强制类型转换时需要注意:当整数值的类型的有效范围由宽变窄时,会截掉一定数量的高位二进制数。与这个类似的还有把一个浮点数类型的值转换为整数类型值时,浮点数类型的小数部分会被全部截断:
func main() {
var a int16 = 428 //00000001 10101100
fmt.Println(int8(a)) // -84
// 截断高8位为:10101100。Go中用二进制补码表示数值。转成原码为为 11010100 即十进制-84
}
浮点数的精度有限,尽量不要做浮点数运算结果的比较:
func main() {
var f float32 = 16777216 // 1 << 24
fmt.Println(f == f+1) // false
var a float32 = 1.23
var b float32 = 1.25
fmt.Println(a-b) // -0.01999998
}
iota常量让用二进制位做标记更简单了。在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一:
const ( FlagUp Flags = 1 << iota // 第一种标记 FlagBroadcast // 第二种标记 FlagLoopback // 第三种标记 FlagPointToPoint // 第四种标记 FlagMulticast // 第五种标记 )
下篇预告
【Go语言踩坑系列(二)】字符串
以上所述就是小编给大家介绍的《【Go语言踩坑系列(一)】基本数据类型》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 编译型语言、解释型语言、静态类型语言、动态类型语言概念与区别
- Python 到底是强类型语言,还是弱类型语言?
- 6. Go 语言数据类型:字典与布尔类型
- 智能合约基础语言(五):Solidity变量类型:引用类型
- GO语言的接口类型
- 7. Go 语言数据类型:指针
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ggplot2:数据分析与图形艺术
哈德利·威克姆 (Hadley Wickham) / 统计之都 / 西安交通大学出版社 / 2013-5-1 / CNY 46.00
中译本序 每当我们看到一个新的软件,第一反应会是:为什么又要发明一个新软件?ggplot2是R世界里相对还比较年轻的一个包,在它之前,官方R已经有自己的基础图形系统(graphics包)和网格图形系统(grid包),并且Deepayan Sarkar也开发了lattice包,看起来R的世界对图形的支持已经足够强大了。那么我们不禁要问,为什么还要发明一套新的系统? 设计理念 打个比......一起来看看 《ggplot2:数据分析与图形艺术》 这本书的介绍吧!