Golang变量&常量&数据类型
Go定义变量
Go语言里面定义变量有多种方式。使用var关键字是Go最基本的定义变量方式,与C语言不同的是Go把变量类型放在变量名后面:
//定义一个名称为“variableName”,类型为"type"的变量
var variableName type
定义多个变量
//定义三个类型都是“type”的变量
var vname1, vname2, vname3 type
定义变量并初始化值
//初始化“variableName”的变量为“value”值,类型是“type”
var variableName type = value
同时初始化多个变量
/*
定义三个类型都是"type"的变量,并且分别初始化为相应的值
vname1为v1,vname2为v2,vname3为v3
*/
var vname1, vname2, vname3 type= v1, v2, v3
你是不是觉得上面这样的定义有点繁琐?没关系,因为Go语言的设计者也发现了,有一种写法可以让它变得简单一点。我们可以直接忽略类型声明,那么上面的代码变成这样了:
/*
定义三个变量,它们分别初始化为相应的值
vname1为v1,vname2为v2,vname3为v3
然后Go会根据其相应值的类型来帮你初始化它们
*/
var vname1, vname2, vname3 = v1, v2, v3
你觉得上面的还是有些繁琐?好吧,我也觉得。让我们继续简化:
/*
定义三个变量,它们分别初始化为相应的值
vname1为v1,vname2为v2,vname3为v3
编译器会根据初始化的值自动推导出相应的类型
*/
vname1, vname2, vname3 := v1, v2, v3
现在是不是看上去非常简洁了?:=这个符号直接取代了var和type,这种形式叫做简短声明。不过它有一个限制,那就是它只能用在函数内部;在函数外部使用则会无法编译通过,所以一般用var方式来定义全局变量。
_(下划线)是个特殊的变量名,任何赋予它的值都会被丢弃。在这个例子中,我们将值35赋予b,并同时丢弃34:
_, b := 34, 35
Go对于已声明但未使用的变量会在编译阶段报错,比如下面的代码就会产生一个错误:声明了i但未使用。
package main
func main() {
var i int
}
如下代码,
func define_var() {
var a, b, c int = 1, 2, 3
fmt.Printf("%d-%d-%d\n", a, b, c)
var e, d, f = 4, 5, 6
fmt.Printf("%d-%d-%d\n", e, d, f)
o, p, q := 7, 8, 9
fmt.Printf("%d-%d-%d\n", o, p, q)
_, r := 12, 13
fmt.Printf("%d", r)
}
Go全局变量
package main
import (
"fmt"
)
//定义全局变量
var (
a string = "hello"
b string = "world"
c int
d int32
)
var e int = 32
func main() {
fmt.Println("hello world")
fmt.Printf("%s-%s-%f-%d", a, b, c, d)
fmt.Printf("全局变量e=%d", e)
}
全局变量就是在函数作用域外定义的变量。
Go常量
所谓常量,也就是在程序编译阶段就确定下来的值,而程序在运行时无法改变该值。在Go程序中,常量可定义为数值、布尔值或字符串等类型。
它的语法如下:
const constantName = value
//如果需要,也可以明确指定常量的类型:
const Pi float32 = 3.1415926
下面是一些常量声明的例子:
const Pi = 3.1415926
const i = 10000
const MaxThread = 10
const prefix = "astaxie_"
Go数值类型
如下代码所示的为go支持的数值类型,
func data_type() {
var v_bool bool
var v_byte byte
var v_rune rune
var v_int8 int8
var v_int16 int16
var v_int32 int32
var v_int64 int64
var v_uint8 uint8
var v_uint16 uint16
var v_uint32 uint32
var v_uint64 uint64
var v_float32 float32
var v_float64 float64
fmt.Printf("%-20s%-20s%-20s%-50s\n",
"Type", "Sizeof", "DefaultValue", "Description")
fmt.Printf("%-20s%-20d%-20t%-50s\n",
"bool", unsafe.Sizeof(v_bool), v_bool, "")
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"byte", unsafe.Sizeof(v_byte), v_byte, "0 - "+strconv.Itoa(math.MaxUint8))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"rune", unsafe.Sizeof(v_rune), v_rune, strconv.Itoa(math.MinInt32)+" - "+strconv.Itoa(math.MaxInt32))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"int8", unsafe.Sizeof(v_int8), v_int8, strconv.Itoa(math.MinInt8)+" - "+strconv.Itoa(math.MaxInt8))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"int16", unsafe.Sizeof(v_int16), v_int16, strconv.Itoa(math.MinInt16)+" - "+strconv.Itoa(math.MaxInt16))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"int32", unsafe.Sizeof(v_int32), v_int32, strconv.Itoa(math.MinInt32)+" - "+strconv.Itoa(math.MaxInt32))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"int64", unsafe.Sizeof(v_int64), v_int64, strconv.Itoa(math.MinInt64)+" - "+strconv.Itoa(math.MaxInt64))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"uint8", unsafe.Sizeof(v_uint8), v_uint8, "0 - "+strconv.Itoa(math.MaxUint8))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"uint16", unsafe.Sizeof(v_uint16), v_uint16, "0 - "+strconv.Itoa(math.MaxUint16))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"uint32", unsafe.Sizeof(v_uint32), v_uint32, "0 - "+strconv.Itoa(math.MaxUint32))
fmt.Printf("%-20s%-20d%-20d%-50s\n",
"uint64", unsafe.Sizeof(v_uint64), v_uint64, "0 - "+strconv.FormatUint(math.MaxUint64, 10))
fmt.Printf("%-20s%-20d%-20f%-50s\n",
"float32", unsafe.Sizeof(v_float32), v_float32, "Max: "+strconv.FormatFloat(math.MaxFloat32, 'f', 6, 32))
fmt.Printf("%-20s%-20d%-20f%-50s\n",
"float64", unsafe.Sizeof(v_float64), v_float64, "")
}
运行结果,
Type Sizeof DefaultValue Description
bool 1 false
byte 1 0 0 - 255
rune 4 0 -2147483648 - 2147483647
int8 1 0 -128 - 127
int16 2 0 -32768 - 32767
int32 4 0 -2147483648 - 2147483647
int64 8 0 -9223372036854775808 - 9223372036854775807
uint8 1 0 0 - 255
uint16 2 0 0 - 65535
uint32 4 0 0 - 4294967295
uint64 8 0 0 - 18446744073709551615
float32 4 0.000000 Max: 340282346638528859811704183484516925440.000000
float64 8 0.000000
注意:
-
rune 是 int32 的别名,可以用来存储 Unicode 标准中定义的任一字符。
-
byte 是 uint8 的别名
Go数值类型-uint && int
Go还定义了三个依赖系统的类型,uint,int和uintptr。因为在32位系统和64位系统上用来表示这些类型的位数是不一样的。
引用:http://golanghome.com/post/5
对于32位系统
uint=uint32
int=int32
uintptr为32位的指针
对于64位系统
uint=uint64
int=int64
uintptr为64位的指针
Go字符串类型
如下代码所示,定义字符串的多种方式
package main
import (
"fmt"
)
var address string
var emptyString string = "" // 声明了一个字符串变量,初始化为空字符串
func main() {
var name string = "liyanxin"
no, yes, maybe := "no", "yes", "maybe" // 简短声明,同时声明多个变量
japaneseHello := "Konichiwa" // 同上
address = "address"
fmt.Println(name)
fmt.Printf("%s %s %s\n", no, yes, maybe)
fmt.Printf("%s\n", japaneseHello)
fmt.Printf("%s\n", address)
}
在go中字符串类型是不可变的,要想修改怎么办?
s := "hello"
c := []byte(s) // 将字符串 s 转换为 []byte 类型
c[0] = 'c'
s2 := string(c) // 再转换回 string 类型
fmt.Printf("%s\n", s2)
还可以使用字符串的切片来完成字符串的修改,
s := "hello"
s = "c" + s[1:] // 字符串虽不能更改,但可进行切片操作
fmt.Printf("%s\n", s)
引用和参考:
http://xhrwang.me/2014/12/22/golang-fundamentals-1-types-variables-constants.html
https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/02.2.md
===========END===========