package main
import "fmt"
func main() {
fmt.Println("hello world")
}
package main
import "fmt"
// 全局变量
var ans = 123
var cnt int
func main() {
// 单个局部变量
a := 114514
// 多个局部变量
b, c := 114, 514
fmt.Println(a, b, c)
fmt.Println(ans)
fmt.Println(cnt)
}
使用 const
关键字
package main
import "fmt"
func main() {
const PI = 3.14
fmt.Println(PI)
}
package main
import "fmt"
// 前面是入参,后面是返回值
func getUpDown(n float64) (x float64, y float64) {
return n - 1, n + 1
}
func main() {
const PI = 3.14
fmt.Println(getUpDown(PI))
}
Go 默认为值传递,传指针可以实现引用传递。
*
&
func swap(x *int, y *int) {
var temp int
temp = *x /* 保存 x 地址上的值 */
*x = *y /* 将 y 值赋给 x */
*y = temp /* 将 temp 值赋给 y */
}
func main() {
// ...
swap(&a, &b)
}
return
后的调用,类似于 Java 的 finally。在 return 之后执行。
如果一个函数中有多个defer语句,它们会以栈顺序执行。
func Demo(){
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
defer fmt.Println("4")
}
func main() {
Demo()
}
4
3
2
1
运行时panic异常一旦被引发就会导致程序崩溃。
recover
函数可以在当前的程序从运行时 panic 的状态中恢复并重新获得流程控制权。
recover只有在defer调用的函数中有效。
package main
import "fmt"
func Demo(i int) {
// 必须放在最上面
defer func() {
err := recover()
if err != nil {
fmt.Println("err:", err)
}
}()
var arr [10]int
fmt.Println(arr[i])
}
func main() {
Demo(10)
fmt.Println("正常运行")
}
err: runtime error: index out of range [10] with length 10
正常运行
Slice 的切片相当于动态数组
// 先定义再初始化
var arr []int
arr = make([]int, 3)
// 定义同时初始化
arr2 := make([]int, 3)
// 获取长度
len(arr)
// 获取容量
cap(arr)
copy:拷贝切片
append:追加元素
对于追加不需要考虑容量限制,切片会自动扩容(原容量2倍)。
package main
import "fmt"
func main() {
var arr []int
// 需要赋值给自己(语法难崩...)
arr = append(arr, 1, 2, 3)
fmt.Println(arr)
}
吐槽:Map 叫集合、Slice 叫切片…终于知道为什么要说英文名了 😅🙏🏻
package main
import "fmt"
func main() {
// key: string
// value: int
m := make(map[string]int, 10)
m["apple"] = 1
m["banana"] = 2
// 字面量创建
n := map[string]int{
"apple": 1,
"banana": 2,
}
// 遍历 Map
for k, v := range m {
fmt.Printf("key=%s, value=%d\n", k, v)
}
// 删除元组
delete(n, "apple")
}
结构体在函数入参中是值传递
package main
import "fmt"
type Book struct {
title string
price float64
}
func increasePrice(book *Book) {
book.price *= 1.2
}
func main() {
var book Book
book.title = "《Golang 从入门到字节》"
book.price = 100
fmt.Println(book)
// 结构体是值传递!!!
increasePrice(&book)
fmt.Println(book)
}
{《Golang 从入门到字节》 100}
{《Golang 从入门到字节》 120}
Golang 不是面向对象编程的语言,使用结构体作为对象。
首字母大写表示 public,首字母小写表示 private。
package main
import "fmt"
type Student struct {
name string
age int
score int
}
func (s *Student) GetName() string {
return s.name
}
func (s *Student) SetName(name string) {
s.name = name
}
func (s *Student) Show() {
fmt.Println(*s)
}
func main() {
student := Student{
name: "wmh",
age: 22,
score: 100,
}
fmt.Println(student.GetName())
student.SetName("yixuan")
student.Show()
}
😅 这语法要吐了
package main
import "fmt"
type Student struct {
name string
age int
score int
}
func (s *Student) GetName() string {
return s.name
}
func (s *Student) SetName(name string) {
s.name = name
}
func (s *Student) Show() {
fmt.Println(*s)
}
// 继承 Student
type CollageStudent struct {
Student
class string
}
// 重写子类方法
func (s *CollageStudent) Show() {
fmt.Println(*s)
}
func main() {
var stu CollageStudent
stu.age = 22
stu.class = "软件工程"
stu.name = "wmh"
fmt.Println(stu.GetName())
stu.SetName("yixuan")
stu.Show()
}
使用 interface
接口实现多态
package main
import "fmt"
// 接口
type Person interface {
talk()
}
type Student struct {
name string
}
func (stu *Student) talk() {
fmt.Println(stu.name + ": student talk")
}
type Teacher struct {
name string
}
func (tea *Teacher) talk() {
fmt.Println(tea.name + ": teacher talk")
}
func main() {
var p1, p2 Person
p1 = &Student{"wmh"}
p1.talk()
p2 = &Teacher{"yx"}
p2.talk()
}
wmh: student talk
yx: teacher talk
可以使用 interface{}
引用任意类型数据(类似于 Java 的 Object,或者 TS 的 any)
package main
import "fmt"
func myPrint(arg interface{}) {
fmt.Println("------")
fmt.Println(arg)
fmt.Println("------")
}
func main() {
n := 114514
str := "wahaha"
myPrint(n)
myPrint(str)
}
将空接口类型(类比 Object)判断并转换成具体子类
func main() {
var x interface{} = 114514
n, ok := x.(int)
fmt.Println(n, ok)
// 114514 true
var y interface{} = "114514"
m, ok := y.(int)
fmt.Println(m, ok)
// 0 false
}