go语言初识——数据类型
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
go
Go是2009年开源的编程语言Go语言具有以下特性语法简洁、并发编程、编译迅速、数组安全、丰富的内置类型、错误处理、匿名函数和闭包、反射、函数多返回值、自动垃圾回收
Go语言最初由Google公司的Robert Griesemer、Ken Thompson和Rob Pike三个大牛于2007年开始设计发明他们最终的目标是设计一种适应网络和多核时代的C语言。所以Go语言很多时候被描述为“类C语言”或者是“21世纪的C语言”当然从各种角度看Go语言确实是从C语言继承了相似的表达式语法、控制流结构、基础数据类型、调用参数传值、指针等诸多编程思想。但是Go语言更是对C语言最彻底的一次扬弃它舍弃了C语言中灵活但是危险的指针运算还重新设计了C语言中部分不太合理运算符的优先级并在很多细微的地方都做了必要的打磨和改变。
go与C语言区别
-
包声明(自说明)编写源文件时必须在非注释的第一行指明这个文件属于哪个包如package main。
-
引入包(头文件)其实就是告诉Go 编译器这个程序需要使用的包如import "fmt"其实就是引入了fmt包。
-
函数和c语言相同即是一个可以实现某一个功能的函数体每一个可执行程序中必须拥有一个main函数。
-
变量Go 语言变量名由字母、数字、下划线组成其中首个字符不能为数字。
-
语句/表达式在 Go 程序中一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾因为这些工作都将由 Go 编译器自动完成。
-
注释和c语言中的注释方式相同可以在任何地方使用以 // 开头的单行注释。以 /* 开头并以 */ 结尾来进行多行注释且不可以嵌套使用多行注释一般用于包的文档描述或注释成块的代码片段。
需要注意的是标识符是用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母和数字、下划线_组成的序列但是第一个字符必须是字母或下划线而不能是数字。
当标识符包括常量、变量、类型、函数名、结构字段等等以一个大写字母开头如Group1那么使用这种形式的标识符的对象就可以被外部包的代码所使用客户端程序需要先导入这个包这被称为导出像面向对象语言中的 public
标识符如果以小写字母开头则对包外是不可见的但是他们在整个包的内部是可见并且可用的像面向对象语言中的 protected。
helloworld
package main
import "fmt"
func main(){
fmt.Println("hello world!")
}
程序执行
go build main.go ---> 生成二进制可执行文件
go run main.go ---> 可直接执行
数据类型
在 Go 编程语言中数据类型用于声明函数和变量。
数据类型的出现是为了把数据分成所需内存大小不同的数据编程的时候需要用大数据的时候才需要申请大内存就可以充分利用内存。具体分类如下
类型 | 解释 |
---|---|
布尔型 | 布尔型的值只可以是常量 true 或者 false |
数字类型 | 整型 int 和浮点型 float。Go 语言支持整型和浮点型数字并且支持复数其中位的运算采用补码 |
字符串类型 | 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本 |
派生类型 | 指针类型Pointer、 数组类型、结构化类型(struct)、Channel类型、函数类型、切片类型、接口类型、Map 类型 |
变量
定义
定义变量格式为
var varname typename
如定义一个int类型变量
package main
import "fmt"
func main() {
var a int = 27
fmt.Println(a)
}
若变量未进行显式初始化则为其赋值为空或者0值
-
数值类型包括complex64/128为0
-
布尔类型为 false
-
字符串为 “”
-
以下几种类型零值为nil
var a *int var a []int var a map[string] int var a chan int var a func(string) int var a error // error 是接口
类型推导
即进行显式初始化时可省略变量类型由编译器判断
var boolvar = true
简短声明 :=
可省去
var typename
的类型推导但必须声明并初始化格式
varname := something
如
a := 1
也可以同时初始化多个变量
a, b, c := 1, 2, 3
此用法比之前定义变量更加方便快捷但有所限制
-
它只能用在函数内部在函数外部使用则会无法编译通过所以一般用
var
方式来定义全局变量
var ( s1 int = 1 s2 bool = true )
-
必须声明并初始化即:=左侧的varname队列必须有未声明过的变量
func main() {// 即:=左侧只要有未声明的变量就可以使用 var a int = 2 a, b := 1, "123" }
匿名变量
用于占位
匿名变量是一个下画线_这本身就是一个特殊的标识符被称为空白标识符。它可以像其他标识符那样用于变量的声明或赋值任何类型都可以赋值给它但任何赋给这个标识符的值都将被抛弃因此这些值不能在后续的代码中使用也不可以使用这个标识符作为变量对其它变量进行赋值或运算。
使用匿名变量时只需要在变量声明的地方使用下画线替换即可。
匿名变量不占用内存空间不会分配内存。匿名变量与匿名变量之间也不会因为多次声明而无法使用
a, b, _ := 1, "123", 2
常量
常量是在程序运行时不会被修改的量。常量中的数据类型只可以是布尔型、数字型整数型、浮点型和复数和字符串型
格式
const variable [type] = value
const c, d = 3, "4"
编译时函数使用
可使用内置函数初始化其在编译时计算
常量可以用len()等内置函数计算表达式的值在常量表达式中函数必须是内置函数否则编译不通过
func main() {
const (
a = "123"
b = len(a)
)
fmt.Println(a, b)
}
//123 3
iota
iota为批常量计数(即为一批常量赋值时的计数)
iota是一种特殊常量可以认为是一个可以被编译器修改的常量。iota在const关键字出现时将被重置为0const中每新增一行常量声明iota计数一次。
在批赋值中途插入新的变量类型不影响iota的计数
const (
a, b = iota, iota //iota = 0
c, d //iota = 1
e, f = "1", "2" //iota = 2
g, h = iota, iota //iota = 3
)
fmt.Println(a, c, d, e, f, g, h)
//输出 0 1 1 1 2 3 3 0 1
并且常量的类型推导是根据赋值来确定的如果未进行赋值则以前一行所赋值再次赋值
const (
a, b = iota, "iota"
c, d
)
fmt.Println(a, b, c, d)
//0 iota 1 iota
若为如下情况,编译器无法推导e的值产生错误
const (
a, b = iota, "iota"
c, d, e//err
)
使用隐匿变量控制iota的值
func main() {
const (
_ = 0
a = iota
_
_
b = iota
)
fmt.Println(a, b)
}
//1 4
单独的常量赋值认为是单独的一批
func main() {
const a = iota
const b = iota
fmt.Println(a, b)
}
// 0 0
基本类型
类型 | 描述 |
---|---|
uint8 / uint16 / uint32 / uint64 | 无符号 8 / 16 / 32 / 64位整型 |
int8 / int16 / int32 / int64 | 有符号8 / 16 / 32 / 64位整型 |
float32 / float64 | IEEE754 32 / 64 位浮点型数 |
complex64 / complex128 | 32 / 64 位实数和虚数 |
byte | 类似 uint8 |
rune | 类似 int32 |
uintptr | 无符号整型用于存放一个指针 |
指针
与C相同Go语言让程序员决定何时使用指针。变量其实是一种使用方便的占位符用于引用计算机内存地址。Go 语言中的的取地址符是&
放到一个变量前使用就会返回相应变量的内存地址。
但go语言指针的使用类似于引用
指针变量其实就是用于存放某一个对象的内存地址。
func main() {
var a = 1
var p = &a
var p1 *int
fmt.Println(a, p, p1)
p1 = p
fmt.Println(a, p, p1)
}
//1 0xc0000a4000 <nil>
//1 0xc0000a4000 0xc0000a4000
若定义但为赋值默认为nil(即null)
数组
数组使用与c语言类似
格式
var variable_name [SIZE] variable_type
go语言数组可对数组内一下标进行初始化
//声明数组
var ar [3]int
//直接初始化
var arr = [3]int{1} //[1 0 0]
var arr1 = [3]int{1, 1: 2}//[1 2 0]
//使用简短声明进行初始化
brr := [3]int{1, 2}//[1 2 0]
brr1 := [3]int{0: 3, 1: 4}//[3 4 0]
//未知长度是时使用[...]进行占位
var crr = [...]int{1, 9: 3}//[1 0 0 0 0 0 0 0 0 3]
crr1 := [...]int{1, 2, 3, 4, 5}//[1 2 3 4 5]
数组名
c语言的数组名代表一个指针指向数组
go的数组为一个变量类型名称即是这个变量
所以go中使用数组名赋值即是拷贝整个数组使用指针传递数组减少开销
func main() {
arr := [...]int{1, 2, 3}
var brr = arr
var p = &brr
fmt.Println(arr)
fmt.Println(brr)
fmt.Println(&brr)
fmt.Println(p)
fmt.Println(*p)
}
结构体
type Book struct {
_BookName string
_Author string
}
func main() {
book1 := Book{"红楼梦", "曹雪芹"}
fmt.Println(book1)
var book2 = Book{_BookName: "三体", _Author: "刘慈欣"}
fmt.Println(book2._BookName, book2._Author)
//结构体指针访问时使用 . 而不是->
p := &book1
fmt.Println(p._BookName, p._Author)
}
//{红楼梦 曹雪芹}
//三体 刘慈欣
//红楼梦 曹雪芹