網頁

2021/9/7

Golang 使用func type讓客戶端自行定義介面方法的實作

Go語言使用func type由客戶端實作介面方法。


例如下面的Accumulator struct提供了一個Adder介面屬性讓客戶端自行實作累加的計算方法Add(x int) int。參數xAccumulator.Add()中傳入Accumulator.Total的值。

main.go

package main

import "fmt"

type Adder interface {
    Add(x int) int
}

type Accumulator struct {
    Total int
    Adder
}

func (ac *Accumulator) Add() {
    ac.Total = ac.Adder.Add(ac.Total)
}

type AddFunc func(x int) int

func (af AddFunc) Add(x int) int {
    return af(x) // call client implmentation
}

func main() {
    ac := Accumulator{
        Total: 0,
        // client implmentation
        Adder: AddFunc(func(x int) int {
            return x + 10
        }),
    }

    ac.Add()

    fmt.Println(ac.Total) // 10

    ac.Adder = AddFunc(func(x int) int {
        return x + 1
    })

    ac.Add()
    fmt.Println(ac.Total) // 11

}

透過func typeAddFunc去實作Adder介面,當Accumulator.Adder.Add(x int)Accumulator.Add()中被調用時轉由AddFunc.Add(x int)的實作處理,再轉由AddFunc本身即客戶端的實作來計算。如此便能在客戶端自行定義累加的邏輯。AddFunc類似一個轉接器(adapter)。

但有個疑問是為何不直接用func type就好而要透過介面,例如改成下面,一樣都可以在客戶端去實作邏輯,這點是我尚未弄懂的地方。

main.go

package main

import "fmt"

type Accumulator struct {
    Total   int
    AddFunc AddFunc
}

func (ac *Accumulator) Add() {
    ac.Total = ac.AddFunc(ac.Total)
}

type AddFunc func(x int) int

func main() {
    ac := Accumulator{
        Total: 0,
        // client implmentation
        AddFunc: func(x int) int {
            return x + 10
        },
    }

    ac.Add()

    fmt.Println(ac.Total) // 10

    ac.AddFunc = func(x int) int {
        return x + 1
    }

    ac.Add()
    fmt.Println(ac.Total) // 11

}


沒有留言:

張貼留言