基本语法
# 第一个程序
package main // 程序包名,package main告诉编译器这是一个可执行程序,而不是作为另一个程序的一部分使用的库包;除此以外应与文件名一致
import (
"fmt"
"time"
)
// main函数
func main() {
fmt.Println("Hello, World!")
time.Sleep(1 * time.Second)
}
class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
// Make sure to add code blocks to your code group
# 变量声明
package main
import "fmt"
// 全局变量,只适用方法1、2、3
var aa int
var bb string = "hello"
var cc = true
func main() {
// 方法1:默认的值是0
var a int
fmt.Println("a = ", a)
// 方法2:指定值
var b int = 10
fmt.Println("b = ", b)
// 方法3:根据值自动推导类型
var c = 30
fmt.Println("c = ", c)
var d = "hello"
fmt.Println("d = ", d)
// 方法4(常用):省略var,注意 := 左侧的变量不应该是已经声明过的,否则会导致编译错误
e := 50
fmt.Println("e = ", e)
fmt.Printf("e type is %T", e)
// 打印全局变量
fmt.Printf("aa = %d, bb = %s, cc = %t", aa, bb, cc)
// 声明多个变量
var xx, yy int = 100, 200
fmt.Println("xx = ", xx, "yy = ", yy)
var kk, ll = 300, "hello"
fmt.Println("kk = ", kk, "ll = ", ll)
var (
mm = 400
nn = "hello"
)
fmt.Println("mm = ", mm, "nn = ", nn)
}
# 常量声明
package main
import "fmt"
const (
// iota是go语言的常量计数器,只能在常量的表达式中使用,默认值为0,每行加1
BEIJING = iota // 10 * iota = 0 * 10 = 0,下面类推20、30
SHANGHAI
SHENZHEN
)
func main() {
// 常量(只读)
const a int = 10
fmt.Println("a = ", a)
fmt.Println("BEIJING = ", BEIJING)
fmt.Println("SHANGHAI = ", SHANGHAI)
fmt.Println("SHENZHEN = ", SHENZHEN)
}
# 函数
# 格式
func function_name( [parameter list] ) [return_types] {
函数体
}
# 单返回值
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)
}
package main
import "fmt"
// func swap(x, y string) (r1 string, r2 string)
func swap(x, y string) (r1, r2 string) {
r1 = y
r2 = x
return
}
func main() {
a, b := swap("Google", "Runoob")
fmt.Println(a, b)
}
// Make sure to add code blocks to your code group
# 导包与 init ()
package main
import (
"study/5-init/lib1"
"study/5-init/lib2"
)
func main() {
lib1.Lib1Func()
lib2.Lib2Func()
}
package lib1
func init() {
println("lib1.init")
}
func Lib1Func() {
println("lib1.Lib1Func")
}
package lib2
func init() {
println("lib2.init")
}
func Lib2Func() {
println("lib2.Lib2Func")
}
// Make sure to add code blocks to your code group
Go的init()可以理解为Java的静态代码块吗?
init () 函数在 Go 中有一些特殊的用途,它们是在程序运行期间自动执行的。但是,它们并不完全等同于 Java 中的静态代码块。
在 Java 中,静态代码块是在类被加载时执行的,并且只会执行一次。这些代码块通常用于初始化类的静态变量。
在 Go 中,init () 函数也可以用于初始化变量,但它们有一些其他用途:
- 在 Go 中,init () 函数可以在包中的任何文件中声明,并且在程序运行期间会自动调用。它们不需要被显式地调用,也不需要在任何特定的时间或条件下调用。
- init () 函数可以在多个文件中声明,并且在程序运行期间会按照它们在源代码中的出现顺序依次调用。这使得它们可以用来确保在程序中的某些部分使用之前已经完成了必要的初始化。
- init () 函数不能有任何返回值或者参数。
因此,虽然 init () 函数和 Java 中的静态代码块有一些相似之处,但它们也有一些显著的差异。
# 安装依赖
go get -u gorm.io/gorm
# 匿名导包与别名
在一些场景可,可能只想导入某个包触发 init 函数,而不需要执行具体的函数。但 go 是不允许导入包而不适用的,因此如果想要实现这个场景,则需要
import _ "study/5-init/lib1"
import . "study/5-init/lib2"
func main() {
Lib2Func() // 可以直接使用包中的函数,不需要使用包名
}
_
表示匿名导入,只会触发 init 函数,不会使用包中的其他函数.
表示别名导入,可以直接使用包中的函数,不需要使用包名
# 指针
# 没有使用的场景
package main
import "fmt"
func changeValue(a int) {
a = 100
}
func main() {
var a int = 10
changeValue(a)
fmt.Println(a)
}
输出结果为 10
,因为在 changeValue 函数中,a 是一个值拷贝,修改的是 a 的副本,而不是 a 本身
# 使用指针
package main
import "fmt"
func changeValue(a *int) {
*a = 100
}
func main() {
var a int = 10
changeValue(&a)
fmt.Println(a)
}
输出结果为 100
,因为在 changeValue 函数中,a 是一个指针,修改的是 a 本身
# defer 语句(类似 finally)
func main() {
defer fmt.Println("defer1")
defer fmt.Println("defer2")
fmt.Println("main")
}
输出结果为
main
defer2
defer1
defer的执行顺序
defer1 先入栈,defer2 后入栈,因此先执行 defer2,再执行 defer1
- defer 语句会将其后面跟随的语句进行延迟处理。
- 先执行 return 语句,存储返回值,再执行 defer 语句,最后再返回
上次更新: 2024/05/08, 23:08:39