GO语言:第一节

76 阅读5分钟
//从Hello World开始。

/*
Go代码使用包来组织,包类似与其他语言中的库和模块。
一个包由一个或者多个.go源文件组成,放在一个文件夹中,该文件夹的名字描述了包的作用。
*/

package main //指明该源文件属于main包。

import "fmt" //导入fmt包(就可使用fmt包中的函数)。

func main() { //func 与 { 必须在同一行
	fmt.Println("Hello, 世界") //打印字符串:Hello, 世界。
}

/*
main包比较特殊,它用来定义一个独立的可执行程序,而不是库。
main函数也很特殊,一个项目中只能出现一个,它是程序执行的入口。
Go不需要语句或者声明后面使用分号结尾,除非一行中有多个语句或者声明。
Go对代码格式化要求严格,比如: func必须与{同一行;x + y能在+后面加回车换行,前面就不行等。
*/
//声明

/*
包名本身总是由小写字母组成。比如:main,fmt。
如果一个实体在函数内部声明,它只在函数局部有效。
如果一个实体在函数外部声明,它将对包里面的所有源文件可见。
实体第一个字母的大小写决定其可见性是否跨包。
声明:各一个程序实体命名,并且设定其部分或者全部属性。
4个主要的声明:变量(var),常量(const),类型(type),函数(func)。
*/
package main

import "fmt"

const boilingF = 212.0 //用const声明了一个常量并初始化。

func main() {
	var f = boilingF //用var声明了一个变量并初始化。
	var c = (f - 32) * 5 / 9 ////用var声明了一个变量并初始化。
	fmt.Printf("boiling point = %gF or %gC\n", f, c)
}
/*
由于boilingF是const声明的常量,其值不可改变。
并且boilingF在函数外声明,所以它对main包中所有源文件可访问。
由于f,c是var声明的变量,其值可以改变。
并且f,c是在函数内部声明,是一个仅作用于main函数里的局部变量。
*/
//声明变量的几种方法。

/*
var name type = expression
类型(type)和表达式部分(= expression)可以省略一个,但不能同时省略。
也可以都不省略。

var num int
表示声明了一个int类型的变量num,默认值为0。

var name = 1
表示声明了一个int类型的变量name,赋值为1。

var name uint64 = 1
表示声明了一个uint64类型的变量name,赋值为1。

var i, j, k int
表示声明了三个int类型的变量i, j, k,默认值为0。

var i, j, k = 1, 2, 3
表示表示声明了三个int类型的变量i, j, k,以此赋值为1,2,3。

var i, j, k int = 1, 2, 3
表示表示声明了三个int类型的变量i, j, k,以此赋值为1,2,3。

var f, err = os.Open(name)
os.Open(name)返回两个参数,将返回的第一个参数赋值给f,第二个参数赋值给err。

var(
    a int = 1
    b string = "dad"
)

将以上的var用const替换就是常量的声明

Go语言中不存在为初始化的变量,如果声明是未初始化,则自动初始化未该类型变量的空值(int 0, string "")。
------------------------------------------------------------------------------------------------------
name := expression
name的类型由expression决定。

i := 100
i为int类型,赋值为100。

i, j := 0, 1
i为int类型,赋值为0;j为int类型,赋值为1。

f, err := os.Open(name)
os.Open(name)返回两个参数,将返回的第一个参数赋值给f,第二个参数赋值给err。
------------------------------------------------------------------------------------------------------
x := 1
var ptr *int = &x 
*ptr = 2  
ptr为int类型的指针;&x:表示x的内存地址;*ptr间接访问x的值。
------------------------------------------------------------------------------------------------------
p = new(int)
*int类型的p,指向未命名的int变量。
使用new创建的变量和取其地址的普通变量没有不同,只是不需要变量名。
所以new只是语法上的便利,不是一个基础概念。
需要注意的是new只是一个内置函数,并不是关键字!
*/
//类型声明

/*
type声明定义一个新的命名类型,它和某个已有类型使用相同的底层类型(如:int)。
type name underlying-type.
*/
package tempconv

import "fmt"

type Celsius float64
type Fahrenheit float64

const (
	AbsoulteZeroC Celsius = -273.15
	FreezingC     Celsius = 0
	BoilingC      Celsius = 100
)

func CToF(c Celsius) Fahrenheit { return Fahrenheit(c * 9 / 5 + 32) }
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 /9) }
/*
虽然Celsius和Fahrenheit有相同的底层类型,它们也不能算作同一个数据类型。
所以它们不能使用算数表达式进行计较和合并。
如果类型T和类型T1有相同的底层类型,那么二者是可以相互转换的T(x)或者T1(x),而不改变其值的表达方式。
如果float32类型转为int类型,不仅会改变值的类型,还会改变它的表达方式。(float32将去除小数点)
另外如果两种数据类型差距过大,普通的类型转换( T(x) )将不被支持。(入string转int)
*/

补充

  • Go语言遵循保小不保大的原则,在保证程序不出错的情况下,优先使用占用更小内存的数据类型。
  • 开发中优先使用float64,因为浮点型数据在存储运算的过程中会出现精度丢失,用更高精度的数据类型会更好。
  • Go中没有专门的字符类型,如果要存储单个字符,一般使用byte(int8的同义词)来保存。
  • Go中字符本质是一个整数,直接输出会得到对应的UTF-8编码的码值。
  • 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。
  • 字符串一旦赋值了,字符串就不能修改了:在 Go 中字符串是不可变的。
  • 字符串用双引号表示会识别转义字符。
  • 字符串用反引号表示,将以字符串原生形式输出。 image.png
  • 值类型的变量直接存储值,内存通常在栈中分配。
  • 引用类型变量存储的是地址,这个地址对应的内存存储值。内存通常在堆上分配,由GC来回收。
  • 引用类型:指针,slice,map,chan,interface。