天天一點Go語言——變量、常量、運算符解析

天天一點Go語言——變量、常量、運算符解析

前言

​ 前面簡單說過有關Go語言的基礎語法及其數據類型,大體上了解了Go語言程序的組成,而本文將講述近乎全部編程語言都涉及的變量、常量以及運算符相關內容。算法

1、變量

何爲變量?

​ 對該專業名詞解釋:計算機語言中能儲存計算結果或能表示值抽象概念。變量能夠經過變量名訪問。Go語言中的變量由字母、數字、下劃線組成,首字母不能夠爲數字。耳熟能詳了哈~shell

​ 筆者的理解:我編寫程序的時候須要使用一個值,而且我一直想要重複使用,並且有時候這個值會發生變化等等,因此我須要聲明一個變量來被這個值賦之。編程

怎麼聲明變量?

變量聲明通常格式:數組

var 變量名 變量類型

var:變量聲明關鍵字,表示聲明變量編程語言

其次是變量的名字,最後是變量的類型(如int)ide

固然也有其餘的變化格式,咱們直接看實例:函數

實例1.1——變量格式寫法1

package main
var a1 int = 10
var a2 = "hello world"
var b1 = 11
var b2 string = "你好,世界"
//c1 := 12 //這種不帶聲明格式的只能在函數體中出現,不然會報錯:non-declaration statement outside function body
var c2 bool

func main(){
        println(a1,a2,b1,b2,c2)
        c1 := 12 //這種變量聲明要注意:c1變量沒有被提早聲明過才能夠這樣賦值
        println(c1)
}

運行結果:指針

10 hello world 11 你好,世界 false
12code

固然變量也能夠一塊兒聲明,程序執行時會自動推斷變量類型(與Python相像)blog

實例1.2——變量格式寫法2

package main
//寫法一:
var v1, v2, v3 int
//寫法二:
var v11, v22, v33 = 4, 5, "hello"
//寫法三:(需寫在全局變量中,不能夠寫在函數體內部)
var (
        vv1 int 
        vv2 bool = true
)
func main(){
        v1, v2, v3 = 1, 2, 3
        println(v1,v2,v3)
        println(v11,v22,v33)
        println(vv1,vv2)
}

運行結果:

1 2 3
4 5 hello
0 true

補充說明:

在變量的初始化時省略變量的類型而由系統自動推斷,聲明語句寫上 var 關鍵字實際上是顯得有些多餘了,所以咱們能夠將它們簡寫爲 a := 50 或 b := false。 編譯器對此會自動推斷a爲int類型,b爲bool類型。

​ 這種簡短形式的變量聲明須要注意如下事項:

  • 只能被用在函數體內部;
  • 相同的代碼塊中,不能夠如此重複聲明變量;

另外,變量須要先聲明後使用(全部方式都同樣);當聲明瞭局部變量(函數體內部),而未使用,也會編譯出錯;可是全局變量能夠不使用。

值類型與引用類型

值類型

​ int、float、bool、string這些基本類型都屬於值類型。值類型的典型特徵就是:咱們所賦值的操做在計算機中存儲和使用的過程是這樣的(先作了解便可):

​ 定義變量到內存中,值類型的變量存儲在棧中,賦值,是將該值進行了一個拷貝再將這個拷貝的內容賦予給變量,變量(值類型)與拷貝的值之間的關係:變量直接指向內存中的值。

​ 能夠經過&變量名獲取變量的內存地址,每次獲取的地址可能不同。

實例1.3——值類型變量內存地址

package main

var a int = 10

func main(){
    println(a)
    println(&a)
}

運行結果:

10
0x4a4018

引用類型(先做了解)

​ Go語言中的引用類型有:映射(map)、數組切片(slice)、通道(channel)、方法和函數。

​ Go語言存在垃圾回收器,所以在一個本地變量再也不被使用時就會被回收掉,此時本地變量的生命週期由它們的做用域決定。對於管理本地變量的生命週期,咱們須要用到指針,使用指針就可使得對應變量的生命週期獨立與做用域。

​ 使用指針能控制變量的生命週期,不受做用域的影響,另外變量在傳遞過程當中使成本最小化,而且能夠修改變量的內容,而不是對複製的值進行操做。固然,指針也是一個變量,表示的是存放(保存了)另外一個變量的內存地址,任何被指針保存的內存地址的變量均可以經過指針來修改內容。

&和*理解:
  • 操做符& : 看成二元操做符時,是按位與操做;看成一元操做符時,是返回該變量的內存地址
  • 操做符* : 看成二元操做符時,是相乘的操做;看成一元操做符(解引用操做符)時,是返回該指針指向的變量的值,其實就是解除變量的指針引用,返回該變量的值。

實例1.4——指針的建立與使用

package main
import "fmt"

func main(){
    a := 3
    p := &a //獲取變量a的內存地址,而且將其賦值給p
    fmt.Printf("a的值爲: %v,a的指針爲: %v,p指向的變量的值爲: %v\n",a,p,*p)
}

運行結果:

~~~a的值爲: 3,a的指針爲: 0xc4200160d8,p指向的變量的值爲: 3

​   也就是說*p和a的值是相等的,能夠交換使用。二者都與同一塊內存地址相關聯,任意一個變量進行修改操做都會影響到另外一個變量的值,可是若變量p被賦值其餘變量的指針就不行了

### 空指針

​   當一個指針被定義後沒有分配到任何變量,值就爲nil,叫作空指針。nil在概念上和其它語言的null、None、nil、NULL同樣,都指代零值或空值。

#### 實例1.5——空指針

~~~go
package main

import "fmt"
func main() {
   var  ptr *int
   fmt.Printf("ptr 的值爲 : %x\n", ptr  )
}

~~~運行結果:ptr 的值爲 : 0

# 2、常量

​   Go語言常量就是值的標識符,程序運行時,不會被修改。常量中的數據類型只能夠是bool型、數字型和字符串型。

常量定義格式:

~~~go
const identifier [type] = value

解釋:const ——關鍵字 ,表示該變量將定義爲常量不可更改

實例2.1——常量定義與使用

package main

import "fmt"
const m string = "hello" //顯式類型定義
const n = "world" //隱式類型定義

func main() {
    const LENGTH int = 10
    const WIDTH int = 5
    var area int
    const a, b, c = 1, false, "str" //多重賦值

    area = LENGTH * WIDTH
    fmt.Printf("面積爲 : %d\n", area)
    println(m, n)
    println(a, b, c)
    //m = "wrong" //錯誤示範
    //println(m) //編譯報錯:cannot assign to m,說明const變量不能夠更改
}

運行結果:

面積爲 : 50
hello world
1 false str

固然,常量也可用做枚舉

const (
    Yes = 0
    No = 1
    Notsure = 2
)

iota

​ iota,一個特殊常量,能夠認爲是一個可以被編譯器修改的常量

實例2.2——iota

package main

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //獨立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢復計數
            i          //8
    )
    fmt.Println(a,b,c,d,e,f,g,h,i)
}

運行結果

~~~0 1 2 ha ha 100 100 7 8

從給出結果的現象能夠知道:

一、在go語言編程中,iota是一個會在程序運行過程當中自動變換的常量;

二、在給const修飾的變量賦值時,每次會隱藏性自增1,不管是否是在賦予給定的值;

三、當賦予給定的值給變量後,該變量以後的變量又未賦予其餘的給定的值時,其後面的變量的值和該變量相等;就如上面的d和e,f和g ;可是有例外(看下面的例子)

四、而當變量回歸賦值iota時,將按照自增的結果賦值給變量。

以下面的例子:

#### 實例2.3——有趣的iota

~~~go
package main

import "fmt"
const (
    i=1<<iota   //"<<"——此符號表示的位運算符,左移;此時對應關係爲i——>1<<iota:1左移0位;則i的值爲1  
    j=3<<iota   //此時對應關係爲:j——>3<<iota爲3,iota的值爲1,則左移1位,即0011——>0110=6  
    k           //可是此時關係爲k——>3<<iota,而不是6<<2,iota爲2,k的值爲12
    l 
    m=iota
)  
func main() {    
    fmt.Println("i=",i)   
    fmt.Println("j=",j)   
    fmt.Println("k=",k)
    fmt.Println("l=",l)
    fmt.Println("m=",m)
}

運行結果:

i= 1
j= 6
k= 12
l= 24
m= 4

3、運算符

​ 近乎全部的程序語言都有運算符,運算符的做用無外乎兩個:數學運算和邏輯運算

Go語言內置的運算符有:算術運算符、關係運算符、邏輯運算符、位運算符、賦值運算符、其餘運算符

一、算數運算符

​ 包括:+、-、*、/、%、++、-- 後三個表示取餘,自增,自減

實例3.1——算法運算符演示

package main

import "fmt"

func main() {

   var a int = 21
   var b int = 10
   var c int

   c = a + b
   fmt.Printf("加法:  c 的值爲 %d\n", c )
   c = a - b
   fmt.Printf("減法:  c 的值爲 %d\n", c )
   c = a * b
   fmt.Printf("乘法:  c 的值爲 %d\n", c )
   c = a / b
   fmt.Printf("除法:  c 的值爲 %d\n", c )
   c = a % b
   fmt.Printf("取餘:  c 的值爲 %d\n", c )
   a++
   fmt.Printf("a自增:   值爲 %d\n", a )
   a--
   fmt.Printf("a自減:   值爲 %d\n", a )
}

運行結果:

加法:  c 的值爲 31
減法:  c 的值爲 11
乘法:  c 的值爲 210
除法:  c 的值爲 2
取餘:  c 的值爲 1
a自增:   值爲 22
a自減:   值爲 21

二、關係運算符

包括 == 、!=、>、<、 >=、 <= 分別對應:判斷是否等於,是否不等於,大於,小於,大於等於,小於等於

​ 本文對此不作代碼演示了,由於涉及到控制流程語句下一篇會講

三、邏輯運算符

​ 下圖表列出了全部Go語言的邏輯運算符。假定 A 值爲 True,B 值爲 False。

天天一點Go語言——變量、常量、運算符解析

四、位運算符

​ 位運算符的做用是對整數在內存中的二進制位進行操做。

下表列出了位運算符 &, |, 和 ^ 的計算:表示邏輯上的「與或非」的關係

天天一點Go語言——變量、常量、運算符解析

總結:

&:兩邊爲真才爲真

|:兩邊爲假才爲假

^:兩邊不一樣才爲真

固然還有上述的左移、右移計算。舉例說明:

60&13的結果爲:12,計算方法是60和13轉換爲二進制作按位與運算,即:0011 1100 & 0000 1101= 0000 1100

60|13的結果爲:61,計算方法是60和13轉換爲二進制作按位或運算,即:0011 1100 | 0000 1101= 0011 1101

五、賦值運算符

賦值運算符以下:

天天一點Go語言——變量、常量、運算符解析

六、其餘運算符

主要就是上面所提到的&和*,分別表示爲返回變量存儲地址和指針變量

運算符優先級

有些運算符擁有較高的優先級,二元運算符的運算方向均是從左至右。下表列出了全部運算符以及它們的優先級,由上至下表明優先級由高到低:(推薦編程的時候使用括號提高優先級,也是爲了加強代碼的可讀性)

天天一點Go語言——變量、常量、運算符解析

4、總結

​ 本文講述了go語言中有關變量、常量、運算符的內容。變量中注意定義變量的格式與位置,尤爲是簡明格式,其次是常量,須要留意一個特殊常量iota。最後則是運算符,須要在實際編程的案例中使用才能體會感悟。

相關文章
相關標籤/搜索