欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Go进阶之路——基础了解三

程序员文章站 2022-07-14 20:33:13
...

变量

var 语句定义了一个变量的列表;跟函数的参数列表一样,类型在后面。

就像在这个例子中看到的一样,`var` 语句可以定义在包或函数级别。

package main

import "fmt"

var c, python, java bool

func main() {
	var i int
	fmt.Println(i, c, python, java)
}

输出结果:

Go进阶之路——基础了解三

零值

变量在定义时没有明确的初始化时会赋值为 零值

零值是:

  • 数值类型为 `0`,
  • 布尔类型为 `false`,
  • 字符串为 `""`(空字符串)。
package main

import "fmt"

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)
}

输出结果:

Go进阶之路——基础了解三

%v	the value in a default format(对应值的默认格式)
	when printing structs, the plus flag (%+v) adds field names(打印结构体时,用%+v的方式会添加字段名)

初始化变量

变量定义可以包含初始值,每个变量对应一个。

如果初始化是使用表达式,则可以省略类型;变量从初始值中获得类型。

package main

import "fmt"

var i, j int = 1, 2

func main() {
	var c, python, java = true, false, "no!"
	fmt.Println(i, j, c, python, java)
}

短声明变量

在函数中,`:=` 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。

函数外的每个语句都必须以关键字开始(`var`、`func`、等等),`:=` 结构不能使用在函数外

package main

import "fmt"

func main() {
	var i, j int = 1, 2
	k := 3
	c, python, java := true, false, "no!"

	fmt.Println(i, j, k, c, python, java)
}

 

基本类型

Go 的基本类型有:


bool

string

uint8       无符号8位整数 (0 to 255)
uint16      无符号16位整数 (0 to 65535)
uint32      无符号32位整数 (0 to 4294967295)
uint64      无符号64位整数 (0 to 18446744073709551615)

int8        有符号8位整数 (-128 to 127)
int16       有符号16位整数 (-32768 to 32767)
int32       有符号32位整数 (-2147483648 to 2147483647)
int64       有符号64位整数 (-9223372036854775808 to 9223372036854775807)

//预先声明的数字类型,长度由操作系统的位数决定
uint        32位或64位
int         同uint
uintptr     一个无符号整数,其大小足以存储指针值的范围,32位下为4字节,64位下为8字节

byte        uint8 的别名,用于表示二进制数据的 bytes

rune        int32 的别名,代表一个Unicode码

float32     所有IEEE-754 32位浮点数的集合。math.MaxFloat32表示float32能表示的最大数值,大约是 3.4e38。
            最小值近似为1.4e-45。
float64     所有IEEE-754 64位浮点数的集合。math.MaxFloat64常量大约是 1.8e308。最小值近似为4.9e-324。

complex64   包含float32实部和虚部的复数
complex128  包含float64实部和虚部的复数

为避免可移植性问题,所有数字类型都是特定的类型,除了byte是unit8的别名,rune是int32的别名外,每个类型都是不同的。因此,在表达式或赋值中混合使用不同的数字类型时,需要进行显示转换。例如,即使int32和int在特定体系结构上可能具有相同的大小,也依然是不同的类型。

下面的例子演示了将不同类型的变量的定义,像导入语句一样,“打包”在一个语法块中。

package main

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)
}

输出结果:

Go进阶之路——基础了解三

cmplx包提供了复数的常用常数和常用函数。

%T	a Go-syntax representation of the type of the value(对应值的Go语法表示形式的值类型)

类型转换

表达式 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 在对不同类型之间的项赋值时,总是需要显式转换。

package main

import (
	"fmt"
	"math"
)

func main() {
	var x, y int = 3, 4
	var f float64 = math.Sqrt(float64(x*x + y*y))
	var z int = int(f)
	fmt.Println(x, y, z)
}

上面例子中,如果不进行显示转换的话是会出现编译错误的。

类型推导

在定义一个变量但不指定其类型时(使用没有类型的 var 或 := 语句), 变量的类型由右值推导得出。

当右值定义了类型时,新变量的类型与其相同:

var i int
j := i // j 也是一个 int

但是当右边包含了未指名类型的数字常量时,新的变量就可能是 int 、 float64 或 `complex128`。 这取决于常量的精度:

i := 42           // int
f := 3.142        // float64
g := 0.867 + 0.5i // complex128

我发现Go的类型推导也不是万能的,例如,上文说到Go的int类型的大小在64位操作系统中的范围是(-9223372036854775808 , 9223372036854775807),看如下代码:

package main

import "fmt"

func main() {
	var v  = 1<<64 -1
	fmt.Printf("%T(%v)\n", v,v)
}

运行后:

Go进阶之路——基础了解三

溢出了,类型推导认为 18446744073709551615 是一个int的类型,但是编译时又发现这个数超出了int类型的范围。然而,我却可以说这个数是一个uint64类型的数,因为咱刚才才用过(基本类型内容中)。

常量

常量的定义与变量类似,只不过使用 const 关键字。

常量可以是字符、字符串、布尔或数字类型的值。

常量不能使用 := 语法定义。

package main

import "fmt"

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)
}

 输出结果:

Go进阶之路——基础了解三

数值常量

数值常量是高精度的 _值_。

一个未指定类型的常量由上下文来决定其类型。

package main

import "fmt"

const (
	Big   = 1 << 100
	Small = Big >> 99
)

func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
	return x * 0.1
}

func main() {
	//fmt.Println(Big)
	fmt.Println(needInt(Small))
	//fmt.Println(needInt(Big))
	fmt.Println(needFloat(Small))
	fmt.Println(needFloat(Big))
	fmt.Println(float64(Big))
}

 输出结果:

Go进阶之路——基础了解三

但是 ,数值常量也不能是随意大的值。

当移位运算 1<<512 时,会报错:

Go进阶之路——基础了解三

当这个数达到8.5e183左右,会出现内部编译器错误:

Go进阶之路——基础了解三

以上可能是我闲的。。。