go语言的基础组成有如下几个部分:
从hello world开始。
package main
import "fmt"
func main() {
// hello
/* world */
fmt.Println("hello world")
}
代码编写完成后,可以直接使用go run xxx.go执行
$ ls main*
main.go
$ go run main.go
hello world
也可以先编译成二进制文件可执行文件再执行
$ ls main*
main.go
$ go build main.go
$ ls main*
main main.go
$ ./main
hello world
结合hello world的代码我们来逐个看看程序的各个部分:
在go代码中,一行代表一个语句结束,不用像C语言那样要以分号";"结尾,go的编译器会自动完成。当然,如果你要在一行中写多个语句,那语句之间必须使用分号间隔。
fmt.Println("hello world") // 不需要;结尾
x := 3;y := x+1;fmt.Println(y) // 多个语句一行需要;间隔,但不建议这样写,可读性差
单行注释使用//
多行注释使用/* 这里注释 */
字符串可以直接使用+号来连接
a := "hello "
msg := a + "world"
fmt.Println(msg) // hello world
go语言设计的比较精简,共有25个保留字(关键字),具体用法后面会详细介绍。
break | default | func | interface | select |
---|---|---|---|---|
case | defer | go | map | struct |
chan | else | goto | package | switch |
const | fallthrough | if | range | type |
continue | for | import | return | var |
类型 | 长度 | 默认值 | 说明 | |
---|---|---|---|---|
布尔值 | bool | 1 | false | |
数字 | int8/uint8 | 1 | 0 | -128~127,0~255 |
int16/uint16 | 2 | 0 | -32768~32767,0~65535 | |
int32/uint32 | 4 | 0 | -21亿~21亿,0~42亿 | |
int/uint | 4或8 | 0 | 32位操作系统长度为4,64位长度为8 | |
int64/uint64 | 8 | 0 | ||
float32 | 4 | 0.0 | ||
float64 | 8 | 0.0 | ||
complex64 | 8 | 32位实数和虚数 | ||
complex128 | 16 | 64为实数和虚数 | ||
字符串 | byte | 1 | 0 | uint8 |
rune | 4 | 0 | Unicode Code Point, int32 | |
string | "" | UTF-8字符串 | ||
派生类型 | 指针(Pointer) | nil | ||
uintptr | 4或8 | nil | 足以存储指针的uint32或者uint64整数 | |
数组类型(array) | 值类型 | |||
结构体(struct) | 值类型 | |||
切片(slice) | nil | 引用类型 | ||
map | nil | 引用类型 | ||
channel | nil | 引用类型 | ||
接口类型(interface) | nil | 接口 | ||
函数类型(function) | nil | 函数 |
var a struct{x int `a`}
var b struct{x int `b`}
// a和b因标签不同,因而属于不同的类型,无法直接互相转换,
可以使用type关键字在全局或者函数内定义新的类型。需要注意的是,新类型不是原类型的别名,它除了和原类型有相同的存储结构外,不保留原类型的任何信息。除非目标类型是未命名类型,否则必须进行显示转换。
package main
import "fmt"
type myarray [3]int // 对未命名类型自定义1个myqrray类型
type myint int // 自定义myint类型
func main() {
a := myarray{1, 2, 3}
fmt.Println(a)
var b [3]int = a // myarray和[3]int是不同类型,但未命名类型可以不用显示转换
fmt.Println(b)
var n myint = 123
var x int = 234
n = x // myint和int是不同类型,不能直接赋值。 Cannot use 'x' (type int) as the type myint
n = myint(x)// 需要进行显示类型转换
fmt.Println(n)
}
从上面类型表格中可以看到,slice、map、channel这三个是引用类型,而像int、bool、数组(array),struct等都是值类型。
那么值类型和引用类型有什么不同点呢?
值类型 | 引用类型 | |
---|---|---|
存储方式 | 数据存储在变量中 | 数据存储在堆中,使用指针指向这块内存 |
赋值操作 | 复制一份数据 | 复制指针,与原值指向同一块内存地址 |
修改操作 | 不影响其他值 | 会影响其他值 |
package main
import "fmt"
type User struct {
Name string
Age int
}
func main() {
// 定义[3]int类型的数组
a1 := [3]int{1, 2, 3}
a2 := a1
a1[0] = 999
fmt.Println(a1) // [999 2 3]
fmt.Println(a2) // [1 2 3]可见a1的修改不影响a2的值
// slice定义切片
s1 := []int{1, 2, 3}
s2 := s1
s1[0] = 999
fmt.Println(s1) // [999 2 3]
fmt.Println(s2) // [999 2 3]对切片s1的修改,会影响到s2,其实s1、s2指向的是同一块内存地址
//struct结构体
u1 := User{
Name: "zhangsan",
Age: 23,
}
u2 := u1
u1.Name = "lisi"
u1.Age = 35
fmt.Println(u1) // {lisi 35}
fmt.Println(u2) // {zhangsan 23} 结构体也是值类型,u1的修改不影响u2
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。