package main
import "fmt"
var test = "test" //在函数外,包级别变量
func main() {
a, b := 1, 2 //a和b,c在main函数内定义,函数级别变量
c := sum(a, b)
fmt.Println(c)
fmt.Println(test)
for i := 0; i < 10; i++ { //i为for循环内定义,为隐式块级别变量
var d = i + 1 //d在for的循环体内,以大括号{}括起来,为显式块级别变量
fmt.Println(d)
}
}
func sum(a, b int) int { //函数参数a和b,在函数内定义,为函数级别变量
fmt.Println(a)
fmt.Println(b)
nu := a + b
return nu
}
package main
import "fmt"
func main() {
var a= "astrng"
fmt.Println(a)
for i := 0; i < 10; i++ {
fmt.Println(i)
}
fmt.Println(i)
}
func testLocal() {
fmt.Println(a)
}
这个代码编译时会报错:
undefined: i
undefined: a
原因:
i:为for循环体内的块级别的局部变量,在定义它的for循环体外访问,就会报undefined。
a:为main函数级别的局部变量,在testLocal函数内无法访问,会报undefined错误。
全局变量
在包级别声明的变量为全局变量。全局变量有以下特征:
全局变量是以小写开头,此全局变量只能在定义它的包(package)内使用。即变量在包内可见。
全局变量是以大写开头,此全局变量可以跨不同包(package)之间使用。即变量在所有地方可见。
全局变量在程序的整个生命周期中都可用。
不能使用:=运算符声明全局变量。
package main
import "fmt"
var a = "astring"
func main() {
testGlobal()
}
func testGlobal() {
fmt.Println(a) //运行结果是,正确打印出a的值“astring”
}
局部变量和全局变量同名
Go语言是运行局部变量和全局变量同名,同名的变量在局部作用域范围,它将遮蔽外部作用域中的变量。
示例:
package main
import "fmt"
var a = "globala"
func main() {
var a = "locala"
fmt.Println(a) //此处的a会遮蔽外面定义的a全局变量,输出locala
}
func testGlobal() {
fmt.Println(a) //此处是全局变量a,输出globala
}
package main
import (
"fmt"
"unsafe"
)
type sample struct {
a int
b string
}
func main() {
s := &sample{a: 1, b: "test"}
//获取b在结构体s的地址
p := unsafe.Pointer(uintptr(unsafe.Pointer(s)) + unsafe.Offsetof(s.b))
}
package main
import (
"os"
log "github.com/sirupsen/logrus"
)
func init() {
// 设置日志格式
log.SetFormatter(&log.JSONFormatter{})
// 设置输出
log.SetOutput(os.Stdout)
// 设置日志级别
log.SetLevel(log.WarnLevel)
}
func main() {
log.WithFields(log.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
log.WithFields(log.Fields{
"omg": true,
"number": 122,
}).Warn("The group's number increased tremendously!")
log.WithFields(log.Fields{
"omg": true,
"number": 100,
}).Fatal("The ice breaks!")
// 设置日志默认的信息,所有使用contextLogger都会复用这些信息
contextLogger := log.WithFields(log.Fields{
"common": "this is a common field",
"other": "I also should be logged always",
})
contextLogger.Info("I'll be logged with common and other field")
contextLogger.Info("Me too")
}
以实例方式使用logrus
package main
import (
"os"
"github.com/sirupsen/logrus"
)
// 创建一个logrus示例
var log = logrus.New()
func main() {
// 设置输出,这和package的方式有所不同,它是以属性的方式赋值
log.Out = os.Stdout
log.WithFields(logrus.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
}
package main
import "fmt"
func main() {
var a = 123 //int
var b = "bstring" //string
var c = 5.6 //float64
var d = true //bool
var e = 'a' //rune
var f = 3 + 5i //complex128
var g = mystruct{name: "test"} //main.MyStruct
fmt.Printf("Type: %T Value: %v\n", a, a)
fmt.Printf("Type: %T Value: %v\n", b, b)
fmt.Printf("Type: %T Value: %v\n", c, c)
fmt.Printf("Type: %T Value: %v\n", d, d)
fmt.Printf("Type: %T Value: %v\n", e, e)
fmt.Printf("Type: %T Value: %v\n", f, f)
fmt.Printf("Type: %T Value: %v\n", g, g)
}
type mystruct struct {
name string
}
多变量声明
多变量声明根据多个变量的类型是否相同分为两种:
相同类型的变量声明
不同类型的变量声明
单个变量的缺省值声明和类型推断同样适用于多变量声明,在此就不重复说明。
相同类型的多变量声明
对于多个变量的声明,如果它们的类型是相同的,可以使用以下格式声明:
var name1, name2, …..,nameN type = value1, value2, …..,valueN
示例:
package main
import "fmt"
func main() {
var a, b int = 8, 9
var c,d int
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
}
输出结果:
8
9
0
0
不同类型多变量声明
对于多个变量的声明,如果它们的类型不同,可以使用以下示例格式:
package main
import "fmt"
func main() {
var (
a int
b int = 10
c string = "cstring"
)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
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