Golang物件導向程式設計之建構函式【struct&new】

吳德寶AllenWu發表於2018-08-10

[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)

}


複製程式碼

相關文章