go语言入门1
一、语法结构
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的代码我们来逐个看看程序的各个部分:
- 第一行:定义了一个main的包。声明包必须是源文件的非注释的第一行,标识这个代码文件属于哪个包。每个go程序必须包含一个名为main的包。
- 第二行:import "fmt"表示需要引入fmt包
- 第三行:定义了一个名为main的函数,对于可执行程序而言,必须包含一个main函数。一般在启动后会第一个执行main哈数(如果有定义init()函数,则init()函数会在main之前执行)
- 下两行:代码注释,同C、java语言,单行注释使用//,多行注释使用/**/
- 下一行: fmt.Println(),是函数内部的处理逻辑,这里调用fmt包内的PrintLn()函数进行打印
- 需要注意的是: ”{ “不能单独一行,必须跟在语句末尾,否则编译器会报错。如使用IDE编写代码一般都会进行提示。
二、基础语法
1、行分隔符
在go代码中,一行代表一个语句结束,不用像C语言那样要以分号"; "结尾,go的编译器会自动完成。当然,如果你要在一行中写多个语句,那语句之间必须使用分号间隔。
fmt.Println("hello world") // 不需要;
结尾
x := 3;
y := x+1;
fmt.Println(y) // 多个语句一行需要;
间隔,但不建议这样写,可读性差
2、注释
单行注释使用//
多行注释使用/* 这里注释 */
3、字符串连接
字符串可以直接使用+号来连接
a := "hello "
msg := a + "world"
fmt.Println(msg) // hello world
4、保留字
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 |
5、数据类型
类型 | 长度 | 默认值 | 说明 | |
---|---|---|---|---|
布尔值 | 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 | 函数 |
5.1 go的类型大致可以分为2大类:
- 命名类型:即类型有固定的名称,如bool、int、string等。
- 未命名类型:即没有固定名称的类型,需要结合声明语句具体确定类型。如array、slice、map、channel、指针等,声明时一般需要指定元素的类型、长度等,由元素类型、长度来确定具体的类型,如[3]int, [5]int属于2个不同的类型。具有相同声明的未命名类型被视为同一个类型:
- 具有相同基类型的指针
- 具有相同元素类型和长度的数组
- 具有相同元素类型的slice
- 具有相同键值类型的map
- 具有相同元素类型和方向的channel
- 具有相同字段序列(字段名、类型、标签、顺序)的匿名struct
- 签名相同(参数和返回值,不包括参数名称)的函数(function)
- 方法集相同(方法名、方法签名相同,次序可不同)的接口(interface)
var a struct{
x int `a`}
var b struct{
x int `b`}
// a和b因标签不同,因而属于不同的类型,无法直接互相转换,
5.2 自定义类型
可以使用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)
}
5.3 值类型和引用类型
从上面类型表格中可以看到,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
}
5.4 类型转换
go的4中类型转换
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: go语言入门1
本文地址: https://pptw.com/jishu/571820.html