包,函数,变量
包
包定义
每个Go程序都是由包组成的, 程序运行的入口是包 main。按照惯例包名与导入路径的最后一个目录一致。例如,"math/rand" 包由 package rand 语句开始
声明包目录
package main
导入
import语句用来导入包,可以使用组合语句导入多个包
import ( "fmt" "math" )
访问权限
首字母大写的名称是被导出的。在导入包之后,只能访问包所导出的名字,任何未导出的名字是不能被包外的代码访问的。
Foo 和 FOO 都是可以被访问的,但名称 foo 是不能被访问的
//math.pi是不能被访问的 //fmt.Println(math.pi) fmt.Println(math.Pi)
函数
声明函数
函数可以没有参数或接受多个参数,注意类型在变量名之后!
//add 接受两个 int 类型的参数 func add(x int, y int) int { return x + y }
当两个或多个连续的函数命名参数是同一类型,则除了最后一个类型之外,其他都可以省略
//x int, y int 被缩写为 x, y int func add(x, y int) int { return x + y }
多值返回
函数可以返回任意数量的返回值
//swap返回了两个值 func swap(x, y string) (string, string) { return y, x } func main() { a, b := swap("hello", "world") fmt.Println(a, b) }
命名返回值
Go的返回值可以被命名,并且就像在函数体开头声明的变量那样使用。返回值的名称应当具有一定的意义,可以作为文档使用
//x, y做为返回值被声明在方法签名中 func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x // 没有参数的 return 语句返回各个返回变量的当前值。这种用法被称作“裸”返回。 // 直接返回语句仅应当用在短函数中。在长的函数中它们会影响代码的可读性。 return } func main() { fmt.Println(split(17)) }
变量
声明变量
var语句定义了一个变量的列表;跟函数的参数列表一样,类型在后面
//变量可以定义在包级别 var c, python, java bool func main() { //变量可以定义在函数级别 var i int fmt.Println(i, c, python, java) }
初始化变量
变量定义可以包含初始值,每个变量对应一个
如果初始化是使用表达式,则可以省略类型;变量从初始值中获得类型
// var i int = 1; var j int = 2 var i, j int = 1, 2 func main() { //var c bool = true; var python bool = false; var java string = "no!" var c, python, java = true, false, "no!" fmt.Println(i, j, c, python, java) }
短声明变量
在函数中 := 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。短声明变量不能用在函数外
func main() { var i, j int = 1, 2 // var k int = 3 k := 3 c, python, java := true, false, "no!" fmt.Println(i, j, k, c, python, java) }
基本数据类型
- bool
- string
- int int8 int16 int32 int64
- uint uint8 uint16 uint32 uint64 uintptr
- byte // uint8 的别名
- rune // int32 的别名,代表一个Unicode码
- float32 float64
- complex64 complex128
int,uint 和 uintptr 类型在32位的系统上一般是32位,而在64位系统上是64位。当你需要使用一个整数类型时,应该首选 int,仅当有特别的理由才使用定长整数类型或者无符号整数类型!
import ( "fmt" "math/cmplx" ) var ( ToBe bool = false MaxInt uint64 = 1<<64 - 1 z complex128 = cmplx.Sqrt(-5 + 12i) ) func main() { const f = "%T(%v)\n" fmt.Printf(f, ToBe, ToBe) fmt.Printf(f, MaxInt, MaxInt) fmt.Printf(f, z, z) }
零值
变量在定义时没有明确的初始化的原始值
- 数值类型为 0
- 布尔类型为 false
- 字符串为 "" (空字符串)
func main() { var i int var f float64 var b bool var s string fmt.Printf("%v %v %v %q\n", i, f, b, s) }
类型转换
表达式 T(v) 将值 v 转换为类型 T
var i int = 42 var f float64 = float64(i) var u uint = uint(f) //更简单的形式 i := 42 f := float64(i) u := uint(f)
与C不同的是Go在不同类型之间的项目赋值时需要显式转换!
类型推导
在定义一个变量却并不显式指定其类型时, 变量的类型由右侧的值推导得出
var i int j := i // j 也是一个 int
当右边包含了未指名类型的数字常量时,新的变量就可能是 int 、 float64 或 complex128 。 这取决于常量的精度:
i := 42 // int f := 3.142 // float64 g := 0.867 + 0.5i // complex128
常量
- 常量的定义与变量类似,只不过使用 const 关键字
- 常量可以是字符、字符串、布尔或数字类型的值
- 常量不能使用 := 语法定义
const Pi = 3.14 func main() { const World = "世界" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day") const Truth = true fmt.Println("Go rules?", Truth) }
数值常量
数值常量是高精度的值,一个未指定类型的常量由上下文来决定其类型
const ( Big = 1 << 100 // 2的100次方 Small = Big >> 99 // 2 ) func needInt(x int) int { return x*10 + 1 } func needFloat(x float64) float64 { return x * 0.1 } func main() { fmt.Println(needInt(Small)) fmt.Println(needFloat(Small)) fmt.Println(needFloat(Big)) // constant 1267650600228229401496703205376 overflows int //fmt.Println(needInt(Big)) }