[TOC]
Golang物件導向程式設計之建構函式【struct&new】
201808
建構函式是一種特殊的方法,主要用來在建立物件時初始化物件,即為物件成員變數賦初始值。特別的一個類可以有多個建構函式 ,可根據其引數個數的不同或引數型別的不同來區分它們,即建構函式的過載。
Golang裡面沒有建構函式,但是Golang卻可以像C++一樣實現類似繼承、建構函式一樣等物件導向程式設計的思想和方法。Golang裡面要實現相關的建構函式定義可以通過通過new來建立建構函式。
一個簡單的建構函式的實現
定義一個結構
type ContentMsg struct {
EffectId int `json:"effect_id"`
Text string `json:"text"`
Data interface{} `json: "data"`
}
複製程式碼
通過new一個物件,或者利用Golang本身的&方式來生成一個物件並返回一個物件指標:
unc NewContentMsg(data, effectId int) *ContentMsg {
instance := new(ContentMsg)
instance.Data = data
instance.EffectId = effectId
return instance
}
func NewContentMsgV2(data, effectId int) *ContentMsg {
return &ContentMsg{
Data: data,
EffectId: effectId,
}
}
複製程式碼
更為優雅的構造的函式的實現
/*
一個更為優雅的建構函式的實現方式
參考:
* 1,專案:"gitlab.xxx.com/xxx/redis"
* 2,連結:https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html
通過這個方式可以方便構造不同物件,同時避免了大量重複程式碼
*/
package main
import (
"fmt"
"time"
"golang.org/x/net/context"
)
type Cluster struct {
opts options
}
type options struct {
connectionTimeout time.Duration
readTimeout time.Duration
writeTimeout time.Duration
logError func(ctx context.Context, err error)
}
// 通過一個選項實現為一個函式指標來達到一個目的:設定選項中的資料的狀態
// Golang函式指標的用法
type Option func(c *options)
// 設定某個引數的一個具體實現,用到了閉包的用法。
// 不僅僅只是設定而採用閉包的目的是為了更為優化,更好用,對使用者更友好
func LogError(f func(ctx context.Context, err error)) Option {
return func(opts *options) {
opts.logError = f
}
}
func ConnectionTimeout(d time.Duration) Option {
return func(opts *options) {
opts.connectionTimeout = d
}
}
func WriteTimeout(d time.Duration) Option {
return func(opts *options) {
opts.writeTimeout = d
}
}
func ReadTimeout(d time.Duration) Option {
return func(opts *options) {
opts.readTimeout = d
}
}
// 建構函式具體實現,傳入相關Option,new一個物件並賦值
// 如果引數很多,也不需要傳入很多引數,只需要傳入opts ...Option即可
func NewCluster(opts ...Option) *Cluster {
clusterOpts := options{}
for _, opt := range opts {
// 函式指標的賦值呼叫
opt(&clusterOpts)
}
cluster := new(Cluster)
cluster.opts = clusterOpts
return cluster
}
func main() {
// 前期儲備,設定相關引數
commonsOpts := []Option{
ConnectionTimeout(1 * time.Second),
ReadTimeout(2 * time.Second),
WriteTimeout(3 * time.Second),
LogError(func(ctx context.Context, err error) {
}),
}
// 終極操作,建構函式
cluster := NewCluster(commonsOpts...)
// 測試驗證
fmt.Println(cluster.opts.connectionTimeout)
fmt.Println(cluster.opts.writeTimeout)
}
複製程式碼