golang-语法
参考:https://m.runoob.com/go/
1 最简单的go程序
package main import "fmt" func main() { fmt.Println("Hello go") }
go run szj.go //执行szj.go
go build ./ //编译成可执行文件,编译后的文件为文件夹名
go build szj.go //编译成可执行文件,编译后的文件为szj
2 go程序的组成
以上面的示例为例
package main //包声明,每个go项目都必须包含至少一个名为main的包 import "fmt" //导入fmt包 func main() { //程序开始执行的函数,main函数是一个项目所必须包含的。注意:{不能单独放到一行 fmt.Println("Hello go") }
3 数据类型
3.1 布尔型
var b bool = true
3.2 数字类型
分为整型和浮点型
3.2.1 整型
int8、int16、int32、int64,uint8、uint16、uint32、uint64
3.2.2 浮点型
float32、float64、complex64、complex128
3.3 字符串类型
3.4 派生类型
包括:指针类型,数组类型,结构化类型(struct),Channel 类型,函数类型,切片类型,接口类型(interface),Map 类型
3.5 强制类型转换
func main() { var sum int = 17 var count int = 5 var mean float32 mean = float32(sum)/float32(count) fmt.Printf("mean 的值为: %f\n",mean) }
4 变量
package main import "fmt" func main() { // 声明一个变量并赋值,注意声明方式:[var 变量名 变量类型 = 变量值] var a string = "Runoob" fmt.Println(a) // 可以一次声明多个变量,并依次赋值。 var b, c int = 1, 2 fmt.Println(b, c) // 没有初始化就为零值 var d int fmt.Println(d) // bool 零值为 false var e bool fmt.Println(e) }
4.1 值类型和引用类型
值类型:int、float、bool、string属于值类型
其他为引用类型
4.2 :=赋值操作符
声明并初始化变量,我们可以省去var关键字和类型声明,a:=50或b:=false形式定义变量并初始化,这种形式只能用在函数体内。
5 常量
package main import "fmt" func main() { const LENGTH int = 10 //定义常量,指定数据类型 const WIDTH = 5 //定义常量,不指定数据类型,由编译器推断 var area int const a, b, c = 1, false, "str" //多重赋值 area = LENGTH * WIDTH fmt.Printf("面积为 : %d", area) println() println(a, b, c) }
6 运算符
运算符和java类似,下面只介绍几个特殊的运算符
6.1 &和*表示获取变量地址和指针变量
package main import "fmt" func main() { var a int = 4 var ptr *int ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */ fmt.Printf("a 的值为 %d\n", a); fmt.Printf("*ptr 为 %d\n", *ptr); }
>go run szj.go
a 的值为 4
*ptr 为 4
7 函数
使用func定义函数,定义函数格式如下
func max(num1, num2 int) int { var result int if (num1 > num2) { result = num1 } else { result = num2 } return result }
函数可以返回多个值
package main import "fmt" func swap(x, y string) (string, string) { return y, x } func main() { a, b := swap("Google", "Runoob") fmt.Println(a, b) }
8 数组
声明数组:var 数组名 [数组大小] 数值类型
func main() { var balance [5] float32 fmt.Println(balance) }
初始化数组
func main() { var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0} //balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0} fmt.Println(balance) }
如果数组长度不确定,可以使用 ... 代替数组的长度
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
或
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
通过指定下标初始化元素
// 将索引为 1 和 3 的元素初始化 balance := [5]float32{1:2.0,3:7.0}
9 指针
func main() { var a int= 20 /* 声明实际变量 */ var ip *int /* 声明指针变量 */ ip = &a /* 指针变量的存储地址 */ fmt.Printf("a 变量的地址是: %x\n", &a ) fmt.Printf("ip 变量储存的指针地址: %x\n", ip ) fmt.Printf("*ip 变量的值: %d\n", *ip ) }
运行结果
空指针,我们使用ptr==nil判断是否为空指针
func main() { var ptr *int fmt.Printf("ptr 的值为 : %x\n", ptr) if ptr == nil { fmt.Printf("ptr是空指针") } }
10 结构体
类似C语言中的结构体
type Books struct { title string author string subject string book_id int } func main() { // 创建一个新的结构体 fmt.Println(Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407}) // 也可以使用 key => value 格式 fmt.Println(Books{title: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407}) // 忽略的字段为 0 或 空 fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"}) }
访问结构体成员
func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ /* book 1 描述 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 /* 打印 Book1 信息 */ fmt.Printf( "Book 1 title : %s\n", Book1.title) fmt.Printf( "Book 1 author : %s\n", Book1.author) fmt.Printf( "Book 1 subject : %s\n", Book1.subject) fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id) }
结构体作为函数参数
func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ /* book 1 描述 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 /* 打印 Book1 信息 */ printBook(Book1) } func printBook( book Books ) { fmt.Printf( "Book title : %s\n", book.title) fmt.Printf( "Book author : %s\n", book.author) fmt.Printf( "Book subject : %s\n", book.subject) fmt.Printf( "Book book_id : %d\n", book.book_id) }
结构体指针
func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ /* book 1 描述 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 /* 打印 Book1 信息 */ printBook(&Book1) } func printBook( book *Books ) { fmt.Printf( "Book title : %s\n", book.title) fmt.Printf( "Book author : %s\n", book.author) fmt.Printf( "Book subject : %s\n", book.subject) fmt.Printf( "Book book_id : %d\n", book.book_id) }
11 切片
11.1切片创建和初始化
func main() { var arr [10]int32 //定义数组 //arr[0] = 1 fmt.Println(arr) var slice0 []int32 //定义切片 fmt.Println(slice0) //var slice1 []int32 = make([]int32, 5) //使用make创建切片并指定长度,并赋值给slice1 slice1 := make([]int32, 5) //也可简写为这样 fmt.Println(slice1) arr2 := [5] int{1,2,3} //数组初始化 slice2 :=[] int {1,2,3 } //切片初始化 fmt.Println(slice2) slice3 := arr2[:] //通过数组初始化切片 fmt.Println(slice3) slice4 := slice3[1:3] //通过切片A初始化切片B fmt.Println(slice4) }
11.2 len()和cap()
切片长度和容量
func main() { var numbers = make([]int,3,5) fmt.Printf("len=%d cap=%d slice=%v\n",len(numbers),cap(numbers),numbers) }
11.3 空(nil)切片
func main() { var numbers []int if(numbers == nil){ fmt.Printf("切片是空的") } }
11.4 append()和copy()
func main() { var numbers []int printSlice(numbers) numbers = append(numbers, 2,3,4) printSlice(numbers) /* 创建切片 numbers1 是之前切片的两倍容量*/ numbers_two := make([]int, len(numbers), (cap(numbers))*2) /* 拷贝 numbers 的内容到 numbers1 */ copy(numbers_two,numbers) printSlice(numbers_two) } func printSlice(x []int){ fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x) }
12 range关键字
作用:用在for循环中迭代数组或map。
迭代数组,返回元素索引和索引对应的值
迭代map,返回key-value对
func main() { nums := []int{2, 3, 4} sum := 0 //range用在数组上。我们不需要使用该元素的索引,所以我们使用空白符"_"省略了 for _, num := range nums { sum += num } fmt.Println("sum:", sum) //range也可以用在map的键值对上。 kvs := map[string]string{"a": "apple", "b": "banana"} for k, v := range kvs { fmt.Printf("%s -> %s\n", k, v) } //range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。 for i, c := range "go" { fmt.Println(i, c) } }
13 go关键字
go关键字用于并发
func main() {
go reportResult.Run()
go cycle.Run()
go temperature.Run()
go pingpong.Run()
}
13 map
声明map方式:map[key数据类型]value数据类型
func main() { var countryCapitalMap map[string]string /*创建map */ countryCapitalMap = make(map[string]string) countryCapitalMap [ "France" ] = "巴黎" countryCapitalMap [ "Japan" ] = "东京" for country,capital := range countryCapitalMap { fmt.Println(country, "首都是", capital) } }
delete()函数用于删除map中的元素
14 面向对象
我们知道,面向对象的基本特征是抽象,封装,继承和多态
golang使用interface和struct来实现面向对象特性。
14.1 interface(抽象)
我们定义一个接口Phone,里面有一个call方法
定义两个类NokiaPhone和IPhone分别实现这两个接口(注意,golang语法和java语法有比较大的差异)
type Phone interface { call() } type NokiaPhone struct { } func (nokiaPhone NokiaPhone) call() { fmt.Println("I am Nokia, I can call you!") } type IPhone struct { } func (iPhone IPhone) call() { fmt.Println("I am iPhone, I can call you!") } func main() { var phone Phone phone = new(NokiaPhone) phone.call() phone = new(IPhone) phone.call() }
通过如下方式,我们定义了NokiaPhone实现了接口的call方法。
func (nokiaPhone NokiaPhone) call() { fmt.Println("I am Nokia, I can call you!") }
注意和函数定义的区别(下面定义了一个无返回值的函数)
func call() { fmt.Println("I am Nokia, I can call you!") }
14.2 封装(struct)
在golang中,我们使用struct封装属性和方法。
下面程序,我们定义了一个类Student,有3个属性name、age、major,1个方法SayHi,1个类似于构造器的方法Init。
注意:在golang中,除slice、map和指针类型属于引用类型外,其他类型都属于值类型。因此我们定义“构造方法”Init时,需要使用指针类型的对象。
属性和方法的公有/私有属性是通过首字母的大小写决定的。比如下例中3个属性是私有的,2个方法是公有的。
type Student struct { name string age int major string } func (s Student) SayHi() { fmt.Printf("Hi, I am %s aged %d, and my major is %s\n", s.name, s.age, s.major) } func (s *Student) Init(name string, age int, major string) { s.name = name s.age = age s.major = major } func main() { s := Student{} s.Init("pirlo", 21, "cs") s.SayHi() }
14.3 继承
golang没有显式的继承,golang的继承通过组合实现的
type Person struct { name string age int } func (p *Person) Init(name string, age int) { p.name = name p.age = age } func (p Person) SayHi() { fmt.Printf("Hi, I am %s, %d years old.\n", p.name, p.age) } type Employee struct { Person company string } func (e *Employee) Init(name string, age int, company string) { e.Person.Init(name, age) e.company = company } func (e Employee) Work() { fmt.Printf("I'm working %s.\n", e.company) } func main() { p := Person{} p.Init("pirlo", 21) p.SayHi() e := Employee{} e.Init("kaka", 22, "milan") e.SayHi() e.Work() }
14.4 多态
type Animal interface { Move() Shout() } type Dog struct { } type Bird struct { } func (dog Dog) Move() { fmt.Println("A dog moves with its legs.") } func (dog Dog) Shout() { fmt.Println("wang wang wang.") } func (bird Bird) Move() { fmt.Println("A bird flys with its wings.") } func (bird Bird) Shout() { fmt.Println("A bird shouts.") } func main() { var animal Animal animal = Dog{} animal.Move() animal.Shout() animal = Bird{} animal.Move() animal.Shout() }