如何在结构类型上调用Go方法?

时间:2017-01-04 02:31:56

标签: go

运行以下内容时出现错误not enough arguments in call to method expression AccountService.Open。在此处运行:https://play.golang.org/p/Z9y-QIcwNy

type AccountService interface {
    Open(no string, name string, openingDate time.Time) AccountService
}

type Account struct {
    Num      string
    Name     string
    OpenDate time.Time
    Balance  float64
}

type SavingsAccount struct {
    InterestRate float32
    Account
}

type CheckingAccount struct {
    TransactionFee float32
    Account
}

func (a SavingsAccount) Open(no string, name string, openingDate time.Time) AccountService {
    return SavingsAccount{
        Account: Account{Num: no,
            Name:     name,
            OpenDate: openingDate,
        },
        InterestRate: 0.9,
    }
}
func (a CheckingAccount) Open(no string, name string, openingDate time.Time) AccountService {
    return CheckingAccount{
        Account: Account{Num: no,
            Name:     name,
            OpenDate: openingDate,
        },
        TransactionFee: 0.15,
    }
}

func main() {
    aliceAcct := AccountService.Open("12345", "Alice", time.Date(1999, time.January, 03, 0, 0, 0, 0, time.UTC))

    fmt.Println("Alice's account =", aliceAcct)
}

3 个答案:

答案 0 :(得分:6)

method expression AccountService.Open的结果是一个类型为func(AccountService, string, string, time.Time) AccountService的函数。代码缺少第一个参数。你可以这样称呼它:

aliceAcct := AccountService.Open(CheckingAccount{}, "12345", "Alice", time.Date(1999, time.January, 03, 0, 0, 0, 0, time.UTC))

playground example

如果您没有有意义的值用作接收器,请改用函数:

func OpenCheckingAccount(no string, name string, openingDate time.Time) AccountService {
    ...
}

如果您需要抽象帐户创建,请将服务定义为函数:

 type AccountService func(no string, name string, openingDate time.Time) AccountType
 func OpenSavings(no string, name string, openingDate time.Time) AccountType { ... }
 func OpenChecking(no string, name string, openingDate time.Time) AccountType { ... }

OpenSavingsOpenChecking函数可用作AccountService。

您需要为服务和帐户使用不同的类型。在这里,我使用AccountService和AccountType。 AccountType不是一个很好的名称,但已经使用了Account。 AccountType可能定义如下:

type AccountType interface {
   func Deposit(int)
   func Withdraw(int)
}

答案 1 :(得分:4)

试试这个

acct := SavingsAccount{}
aliceAcct:= acct.Open("12345", "Alice", time.Date(1999, time.January, 03, 0, 0, 0, 0, time.UTC))
fmt.Println("Alice's account =", aliceAcct)

您需要创建一个正确实现AccountService接口的结构实例

- 编辑 工作示例:play.golang.org

答案 2 :(得分:2)

大多数Go包都会执行以下两项操作之一:

  1. 有一个包级别函数,例如OpenSavingsAccount,它返回一个打开的,初始化的SavingsAccount。

  2. 在名为DefaultSavingsAccount的包中有一个默认变量,并在包级别复制SavingsAccount方法,它们在DefaultSavingsAccount上运行。这是很多功能重复,但所有逻辑都保留在方法中。如果DefaultSavingsAccount不是const并且是接口类型,则可以用其他实现替换它。