首頁  >  文章  >  後端開發  >  golang 型什麼意思

golang 型什麼意思

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼原創
2019-12-10 10:26:043653瀏覽

golang 型什麼意思

type是go語法裡的重要且常用的關鍵字,type絕不只是對應於C/C 中的typedef。 type又有兩種使用方式,一種是型別別名,一種是型別定義,是不是熟悉的C語言(define和typedef)味道?

類型定義

type Student struct {
  name String
  age int
}
type I int

類型別名

type Sdt = Student
type I = int

type有下列幾種用法:

定義結構體

定義介面

類型定義

類型別名

類型查詢

定義結構體

結構體是使用者自訂的一種抽象的資料結構,golang中struct類似於java語言中的class, 在程式設計中,有著舉足輕重的地位。結構體的用法,將會在struct關鍵字中詳細的介紹。下邊來看定義一個結構體的語法格式:

type name struct {
    Field1  dataType
    Field2  dataType
    Field3  dataType
}

定義介面

介面相關知識點,將會在interface關鍵字中詳細介紹,下邊來看一段定義介面的語法格式:

type name interface{
    Read()
    Write()
}

類型定義

使用類型定義定義出來的類型與原始類型不相同,所以不能使用新類型變數賦值給原型別變量,除非使用強制型別轉換。下面來看一段範例程式碼,根據string類型,定義一種新的類型,新類型名稱是name:

type name string

為什麼要使用類型定義呢?

類型定義可以在原始類型的基礎上創造出新的類型,有些場合下可以使程式碼更簡潔,如下邊範例程式碼:

package main
import (
  "fmt"
)
// 定义一个接收一个字符串类型参数的函数类型
type handle func(str string)
// exec函数,接收handle类型的参数
func exec(f handle) {
  f("hello")
}
func main() {
  // 定义一个函数类型变量,这个函数接收一个字符串类型的参数
  var p = func(str string) {
    fmt.Println("first", str)
  }
  exec(p)
  // 匿名函数作为参数直接传递给exec函数
  exec(func(str string) {
    fmt.Println("second", str)
  })
}

輸出資訊是:

first hello
second hello

上邊的範例是類型定義的一種簡單應用場合,如果不使用類型定義,那麼想要實現上邊範例中的功能,應該怎麼書寫這段程式碼呢?

// exec函数,接收handle类型的参数
func exec(f func(str string)) {
  f("hello")
}

exec函數中的參數類型,要替換成func(str string)了,咋一看去也不複雜,但是假如exec接收一個需要5個參數的函數變數呢?是不是感覺參數列表就會很久了。

func exec(f func(str string, str2 string, num int, money float64, flag bool)) {
  f("hello")
}

從上邊的程式碼可以發現,exec函數的參數清單可讀性變差了。下邊再來看看使用類型定義是怎麼實作這個功能:

package main
import (
  "fmt"
)
// 定义一个需要五个参数的函数类型
type handle func(str string, str2 string, num int, money float64, flag bool)
// exec函数,接收handle类型的参数
func exec(f handle) {
  f("hello", "world", 10, 11.23, true)
}
func demo(str string, str2 string, num int, money float64, flag bool) {
  fmt.Println(str, str2, num, money, flag)
}
func main() {
  exec(demo)
}

類型別名

類型別名這個特性在golang1.9中引入。使用型別別名定義出來的型別與原型別一樣,也就是可以與原型別變數互相賦值,又擁有了原型別的所有方法集。給strng類型取一個別名,別名名稱是name:

type name = string

類型別名與型別定義不同之處在於,使用型別別名需要在別名與原型別之間加上賦值符號(=);使用型別定義別名定義的類型與原型別等價,而使用型別定義出來的型別是一種新的型別。

如下邊範例:

package main
import (
  "fmt"
)
type a = string
type b string
func SayA(str a) {
  fmt.Println(str)
}
func SayB(str b) {
  fmt.Println(str)
}
func main() {
  var str = "test"
  SayA(str)
  
  //错误参数传递,str是字符串类型,不能赋值给b类型变量
  SayB(str)
}

這段程式碼在編譯時會出現如下錯誤:

.\main.go:21:6: cannot use str (type string) as type b in argument to SayB

從錯誤訊息可知,str為字串類型,不能當做b類型參數傳入SayB函數中。而str卻可以當做a型別參數傳入到SayA函數中。由此可見,使用型別別名定義的型別與原型別一致,而型別定義定義出來的型別,是一種新的型別。

新增方法給型別方法,會加入到原始型別方法集中

給型別別方法後,原型別也能使用這個方法。下邊請看一段範例程式碼:

package main
import (
  "fmt"
)
// 根据string类型,定义类型S
type S string
func (r *S) Hi() {
  fmt.Println("S hi")
}
// 定义S的类型别名为T
type T = S
func (r *T) Hello() {
  fmt.Println("T hello")
}
// 函数参数接收S类型的指针变量
func exec(obj *S) {
  obj.Hello()
  obj.Hi()
}
func main() {
  t := new(T)
  s := new(S)
  exec(s)
  // 将T类型指针变量传递给S类型指针变量
  exec(t)
}

輸出資訊是:

T hello
S hi
T hello
S hi

上邊的範例中,S是原型,T是S型別別名。在給T增加了Hello方法後,S類型的變數也可以使用Hello方法。說明給型別別名新增方法後,原型別也能使用這個方法。從範例中可知,變數t可以賦值給S型別變數s,所以型別別名是給原型別取了一個小名,本質上沒有發生任何變化。

型別別名,只能對同一個套件中的自訂型別產生作用。舉個例子,golang sdk中有很多個包,是不是我們可以使用型別別名,為sdk包中的結構體型別新增方法呢?答案是:不行。請牢記一點:類型別名,只能對包內的類型產生作用,對包外的類型採用類型別名,在編譯時將會提示如下資訊:

cannot define new methods on non-local type string

類型查詢

類型查詢,就是根據變量,查詢這個變數的類型。為什麼會有這樣的需求呢? goalng中有一個特殊的類型interface{},這個類型可以被任何類型的變量賦值,如果想要知道到底是哪個類型的變量賦值給了interface{}類型變量,就需要使用類型查詢來解決這個需求,範例程式碼如下:

package main
import (
  "fmt"
)
func main() {
    // 定义一个interface{}类型变量,并使用string类型值”abc“初始化
    var a interface{} = "abc"
    
    // 在switch中使用 变量名.(type) 查询变量是由哪个类型数据赋值。
    switch v := a.(type) {
    case string:
      fmt.Println("字符串")
    case int:
        fmt.Println("整型")
    default:
      fmt.Println("其他类型", v)
    }
}

如果使用.(type)查詢類型的變數不是interface{}類型,則在編譯時會報如下錯誤:

cannot type switch on non-interface value a (type string)

如果在switch以外地方使用. (type),則在編譯時會提示如下錯誤:

use of .(type) outside type switch

所以,使用type進行類型查詢時,只能在switch中使用,且使用類型查詢的變數類型必須是interface{}

PHP中文網,有大量免費的Golang入門教學,歡迎大家學習!

以上是golang 型什麼意思的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn