GO常見(jiàn)錯(cuò)誤編程總結(jié):第一篇

一。切片之間通過(guò)append追加

  • 常見(jiàn)錯(cuò)誤編碼
func main(){
  a:=[]int{1,2,3}
  b:=[]int{4,5,6}
//這個(gè)是錯(cuò)誤的編程
  a=append(a, b) 
//正確的編程應(yīng)該是
  a=append(a, b...)
}
//原因:切片之間通過(guò)append追加時(shí)要用 ... 符號(hào),表示將b中的內(nèi)容追加的a中。
//也可以通過(guò) a=append(a, 4, 5, 6)這種方式追加

二。全局變量定義

  • 常見(jiàn)錯(cuò)誤編碼
var(
  a:=10 //錯(cuò)誤編碼
  b=a*2
)
func main(){
  fmt.println(b)
}
//原因:簡(jiǎn)寫方式的定義變量只能在函數(shù)內(nèi)部使用,全局變量不能使用。
//擴(kuò)展:變量在定義時(shí)就初始化時(shí),如果沒(méi)有說(shuō)明類型,編譯器會(huì)根據(jù)所賦的值,自動(dòng)推導(dǎo)

三。 結(jié)構(gòu)體比較

  • 常見(jiàn)錯(cuò)誤代碼
type sn3 struct {
  name string
  age int
}
func main() {
    sn1 := struct {
        age  int
        name string
    }{age: 11, name: "qq"}
    sn2 := struct {
        age  int
        name string
    }{age: 11, name: "qq"}

    if sn1 == sn2 {
        fmt.Println("sn1 == sn2")
    }

    sm1 := struct {
        age int
        m   map[string]string
    }{age: 11, m: map[string]string{"a": "1"}}
    sm2 := struct {
        age int
        m   map[string]string
    }{age: 11, m: map[string]string{"a": "1"}}

    if sm1 == sm2 { //該處代碼報(bào)錯(cuò),編譯不過(guò)
        fmt.Println("sm1 == sm2")
    }
}
  • 知識(shí)點(diǎn)總結(jié)
    1. 結(jié)構(gòu)體之間只能比較是否相等,不能比較大小
    2. 相同類型的結(jié)構(gòu)體之間才能比較,結(jié)構(gòu)體類型是否相同不僅于屬性類型有關(guān),還與定義的屬性順序有關(guān)。例如:sn1和sn2就可以比較,和sn3就不可以比較
    3. 如果 struct 的所有成員都可以比較,則該 struct 就可以通過(guò) == 或 != 進(jìn)行比較是否相等,比較時(shí)逐個(gè)項(xiàng)進(jìn)行比較,如果每一項(xiàng)都相等,則兩個(gè)結(jié)構(gòu)體才相等,否則不相等。那什么是可比較的呢,常見(jiàn)的有 bool、數(shù)值型、字符、指針、數(shù)組等,像切片、map、函數(shù)等是不能比較的

四。類型別名和重新定義新的類型

type  MyType1  int
type MyType2 = int
func main(){
  var a int = 10
  var b MyType1 = a //此處代碼編譯不過(guò)
  var c MyType2 = a
}
  • 考察知識(shí)點(diǎn)
    1. 類型別名與類型定義的區(qū)別
    2. 類型別名的定義用 = 符號(hào)
    3. 第 1 行代碼是基于類型 int 創(chuàng)建了新類型 MyType1,第 2 行代碼是創(chuàng)建了 int 的類型別名 MyType2。所以,第 5行代碼相當(dāng)于是將 int 類型的變量賦值給 MyType1類型的變量,Go 是強(qiáng)類型語(yǔ)言,編譯當(dāng)然不通過(guò);而 MyType2只是 int 的別名,本質(zhì)上還是 int,可以賦值
    4. 可以通過(guò)類型轉(zhuǎn)換賦值 例如:var b MyType1 = MyType1(a)

五。go中iota的使用

const (
     x = iota
     _
     y
     z = "zz"
     k 
     p = iota
 )

func main()  {
    fmt.Println(x,y,z,k,p)  //打印的結(jié)果值為:0, 2, zz, zz, 5
}
  • 考察知識(shí)點(diǎn)
    1. iota是golang語(yǔ)言的常量計(jì)數(shù)器,只能在常量的表達(dá)式中使用
    2. iota在const關(guān)鍵字出現(xiàn)時(shí)將被重置為0(const內(nèi)部的第一行之前)
    3. const中每新增一行常量聲明將使iota計(jì)數(shù)一次(iota可理解為const語(yǔ)句塊中的行索引)

六。go類型選擇(type)

func GetValue() int{
  return 1
}
func main(){
  i:= GetValue()
  switch i.(type){  //此處報(bào)錯(cuò)
    case int:
      fmt.Println("int")
    case string:
      fmt.Println("string")
  }
}
  • 考察知識(shí)點(diǎn)
    1. 類型選擇的語(yǔ)法為:i.(type)
    2. type是固定的關(guān)鍵字,但是i類型必須是interface{} 接口類型,才能使用 i.(type)來(lái)判斷類型

七。切片和數(shù)組細(xì)節(jié)

func test(i...int){
  i[0]=18
}
func mian(){
  a:=[]int{1,2,3}
  test(a...)
  fmt.println(a[0])
  //輸出結(jié)果為,A. 1  B. 18   C.Compilation error
}
  • 考察知識(shí)點(diǎn)
    1. 答案為B
    2. 首先a的類型是一個(gè)切片。由于定義的切片是通過(guò)中括號(hào)的方式定義的而不是通過(guò)make方式定義的,所以切片的len和cap都為切片的長(zhǎng)度,本例中為3 。
    3. 如果如果中括號(hào)中有數(shù)值指定長(zhǎng)度,例如 a:=[3]int{1,2,3},則定義的是數(shù)組類型,而不是切片類型
    4. 切片類型屬于引用類型,所以結(jié)果為B
    5. 如果函數(shù)參數(shù)的類型為可變參數(shù),那么只有切片類型的可以通過(guò) a...三個(gè)點(diǎn)的方式傳遞參數(shù),數(shù)組是不可以的,會(huì)報(bào)錯(cuò)

八。 數(shù)組比較

func main(){
  a:=[2]int{1,2}
  b:=[3]int{1,2}
  fmt.println(a==b)
}
  • 考察知識(shí)點(diǎn)
    1. 編譯報(bào)錯(cuò)
    2. 數(shù)組是值類型可以進(jìn)行比較
    3. 但是是否是同一個(gè)數(shù)組的值類型,除了類型之外,還需要長(zhǎng)度相同。只要有一個(gè)不同就是不同的類型,就不能比較。所以a的長(zhǎng)度為2,b的長(zhǎng)度為3所以不是同一個(gè)類型,所以不能比較。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容