第三篇、变量

一、基础

1、

需要注意的是,go在声明变量的时候将变量的类型放到变量的名称之后,原因是为了避免像c语言那样含糊不清的声明形式,

2、

当一个变量被声明之后,系统自动赋予它该类型的零值:int 为 0,float 为 0.0,bool 为 false,string 为空字符串,指针为 nil。记住,所有的内存在 Go 中都是经过初始化的。

3、

变量的作用域:

如果变量在函数外部声明,那么这个变量就是全局变量

如果变量在函数内部声明,那么这个变量就是局部变量

如果全局变量和局部变量的名字相同,那么在函数内部会执行局部变量,而不是全局变量

4、

变量可以在编译之前就被赋值,赋值给变量使用运算符= ,当然也可以在运行时对变量进行赋值操作

a=15

b=false

5、声明与赋值(初始化)语句也可以结合起来

6、变量的类型也可以自动运行时实现自动推断,这种写法主要用于声明包级别的全局变量

var (

 HOME= os.Getenv(“HOME”)

 USER = os.Getenv(“USER”)

 GOROOT= os.Getenv(“GOROOT”)

)

7、当声明局部变量的时候,应使用间断语声明语法:=

a := 1

package main

import "fmt"
//轻松的声明为指针
    var a,b *int  //nil
    //第一种声明方式
    var a1 int  //0
    var b1 bool  //false
    var str string  ////第二种声明方式
    var (
        a2 int
        b2 bool
        str2 string
    )
    //初始化方式的两种方法,方法一
    var a3=15
    var b3=false
    var str3="hello go"

    //第二种方式
    var (
        a4=15
        b4=false
        str4="hellogo"
    )
func main() {


    fmt.Println(a,b)
    fmt.Println(a1,b1,str)
    fmt.Println(str)
    fmt.Println(a2,b2,str2)
}

二、值类型和应用类型

 1、

所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值 ,值类型的变量的值存储在栈中

2、另外像数组和结构这些复合类型也是值类型

3、使用等号=将一个变量的值赋值给另一个变量的时候如j=i,实际上就是在内存中将i的值进行了拷贝

4、内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同

 5、在go语言中,指针属于引用类型,其他的引用类型还包括slices,mao,channel。被应用的变量会存储在堆中,以便进行垃圾回收

三、打印

如果是使用"Print"或"Println"函数的话,甚至不需要格式化字符串。这些函数会针对数据类型 自动作转换。"Print"函数默认将每个参数以"%v"格式输出,"Println"函数则是在"Print"函数 的输出基础上增加一个换行。一下两种输出方式和前面的输出结果是一致的。

如果要用"Printf"或"Print"函数输出似有的结构类型,之需要为该结构实现一个"String()"方法, 返回相应的字符串就可以了。打印函数会先检测该类型是否实现了"String()"方法,如果实现了则以 该方法返回字符串作为输出。

 函数 fmt.Sprintf 与 Printf 的作用是完全相同的,不过前者将格式化后的字符串以返回值的形式返回给调用者,因此你可以在程序中使用包含变量的字符串

 函数 fmt.Print 和 fmt.Println 会自动使用格式化标识符 %v 对字符串进行格式化,两者都会在每个参数之间自动增加空格,而后者还会在字符串的最后加上一个换行符,%s代表字符串标识符、%v 代表使用类型的默认输出格式的标识符

 四、变量的简短形式

 1、你声明了一个局部变量却没有在相同的代码块中使用它,同样会得到编译错误,但是全局变量是允许声明但不使用

2、

同一类型的多个变量可以声明在同一行,(这是将类型写在标识符后面的一个重要原因)如:

var a, b, c in

3、

多变量可以在同一行进行赋值,如:

a, b, c = 5, 7, "abc"

上面这行假设了变量 a,b 和 c 都已经被声明,否则的话应该这样使用:

a, b, c := 5, 7, "abc"

右边的这些值以相同的顺序赋值给左边的变量,所以 a 的值是 5, b 的值是 7,c 的值是 "abc"

这被称为 并行 或 同时 赋值。

如果你想要交换两个变量的值,则可以简单地使用 a, b = b, a

(在 Go 语言中,这样省去了使用交换函数的必要)

空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。

_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。

并行赋值也被用于当一个函数返回多个返回值时,比如这里的 val 和错误 err 是通过调用 Func1 函数同时得到:val, err = Func1(var1)

五、init函数

变量除了可以在全局声明中初始化,也可以在 init 函数中初始化。这是一类非常特殊的函数,它不能够被人为调用,而是在每个包完成初始化后自动执行,并且执行优先级比 main 函数高。

每一个源文件都可以包含一个或多个 init 函数。初始化总是以单线程执行,并且按照包的依赖关系顺序执行。

一个可能的用途是在开始执行程序之前对数据进行检验或修复,以保证程序状态的正确性

 这里的init初始化和python的__init__类似

练习 推断以下程序的输出,并解释你的答案,然后编译并执行它们。

练习 4.1 local_scope.go:

package main

var a = "G"

func main() {
   n()
   m()
   n()
}

func n() { print(a) }

func m() {
   a := "O"
   print(a)
}
练习 4.2 global_scope.go:

package main

var a = "G"

func main() {
   n()
   m()
   n()
}

func n() {
   print(a)
}

func m() {
   a = "O"
   print(a)
}
练习 4.3 function_calls_function.go

package main

var a string

func main() {
   a = "G"
   print(a)
   f1()
}

func f1() {
   a := "O"
   print(a)
   f2()
}

func f2() {
   print(a)
}
View Code
package main
var a string
func main(){
    a="G"
    print(a)
    f1()
}
func f1(){
    a:="o"
    print(a)
    f2()
}
func f2(){
    print(a)
}
//GOG
View Code
原文地址:https://www.cnblogs.com/pyrene/p/6598554.html