Golang建立建構函式的方法詳解

roc_guo發表於2023-03-04
組合字面量

組合字面量是最直接方式初始化Go物件,假設定義了Book型別,使用字面量初始化程式碼如下:

type Book struct {
  title string
  pages int
}
// creating a new struct instance
b := Book{}
// creating a pointer to a struct instance
bp := &Book{}
// creating an empty value
nothing := struct{}{}

當然還可以直接個屬性賦值:

b := Book{
  title: "Julius Caesar",
  pages: 322,
}

這種方式的優勢是語法直接、簡單易讀。但不能給每個屬性設定預設值。所以當型別包括多個預設值欄位時,需要重複寫預設值欄位賦值語句。舉例:

type Pizza struct {
  slices int
  toppings []string
}
somePizza := Pizza{
  slices: 6,
  toppings: []string{"pepperoni"},
}
otherPizza := Pizza{
  slices: 6,
  toppings: []string{"onion", "pineapple"},
}

上面示例每次都設定slices屬性為6,另外,如果toppings屬性可以為空,如果沒有初始化則為nil,這可能導致錯誤。

自定義建構函式

如果屬性需要設定預設值或進行初始化,自定義建構函式可能會很有用。下面透過NewPizza建構函式定義Pizza例項:

func NewPizza(toppings []string) () {
  if toppings == nil {
    toppings = []string{}
  }
  return Pizza{
    slices: 6,
    toppings: toppings,
  }
}

透過使用建構函式可以自定義例項建立過程:

給欄位設定預設值,當然還可以利用可選引數方式給不同屬性設定預設值。
還可以執行合理性檢查,如toppings是否為nil並初始化。可以利用make或new構造一些資料型別並更好控制記憶體和容量。

從建構函式返回錯誤

當構造屬性時,可能依賴其他系統或庫會產生錯誤,這時返回error。

func NewRemotePizza(url string) (Pizza, error) {
  // toppings are received from a remote URL, which may fail
  toppings, err := getToppings(url)
  if err != nil {
    // if an error occurs, return the wrapped error along with an empty
    // Pizza instance
    return Pizza{}, fmt.Errorf("could not construct new Pizza: %v", err)
  }
  return Pizza{
    slices:   6,
    toppings: toppings,
  }, nil
}

返回錯誤有助於將故障條件封裝在建構函式本身中。

interface建構函式

建構函式可以直接返回interface型別,同時在其中初始化具體型別。如果我們想將結構設為私有,同時將其初始化設為公共,這將很有幫助。

還是用Pizza型別舉例,如果有bakery介面,判斷pizza是否可烘烤型別。首先建立Bakeable介面,然後給Pizza型別增加isBaked欄位:

// Pizza implements Bakeable
type Bakeable interface {
    Bake()
}
type Pizza struct {
    slices   int
    toppings []string
    isBaked  bool
}
func (p Pizza) Bake() {
    p.isBaked = true
}
// this constructor will return a `Bakeable`
// and not a `Pizza`
func NewUnbakedPizza(toppings []string) Bakeable {
    return Pizza{
        slices:   6,
        toppings: toppings,
    }
}
實踐

讓我們來看看Go中關於建構函式命名和組織的一些約定:

基本建構函式

對於簡單建構函式返回型別(如Abc,或Xyz型別),則函式分別命名為NewAbc和NewXyz。對於Pizza例項,則建構函式命名為NewPizza。

主包型別

如果在給定包中,初始化變數為主包型別,可以直接命名為New(無需字首)。舉例,Pizza結構定義在pizza包中,建構函式定義如下:

package pizza
type Pizza struct {
  // ...
}
func New(toppings []string) Pizza {
  // ...
}

當在其他包中呼叫函式時,程式碼為 p := pizza.New() 。

多個建構函式

有時相同型別可能有多個建構函式。為此,我們使用NewXyz名稱的變體來描述每個方法。舉例,下面有三個方法建立Pizza:

  • NewPizza 為主構造方法.
  • NewRemotePizza 基於遠處資源的構造方法.
  • NewUnbakedPizza 返回Bakeable介面型別的構造方法.
  • 到此這篇關於Golang建立建構函式的方法超詳細講解的文章就介紹到這了


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2938153/,如需轉載,請註明出處,否則將追究法律責任。

相關文章