英文:
How to call a Go method on a struct type?
问题
当我运行以下代码时,出现了错误not enough arguments in call to method expression AccountService.Open
。代码如下所示:
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)
}
请点击此处运行代码:https://play.golang.org/p/Z9y-QIcwNy
英文:
I getting the error not enough arguments in call to method expression AccountService.Open
when I run the following. Run here: 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)
}
答案1
得分: 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))
如果你没有有意义的值作为接收器,那么可以使用一个函数代替:
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 { ... }
OpenSavings
和 OpenChecking
函数可以作为 AccountService 使用。
你可能需要为服务和账户使用不同的类型。这里,我使用了 AccountService 和 AccountType。AccountType 不是一个很好的名称,但是 Account 已经被使用了。AccountType 可以定义如下:
type AccountType interface {
func Deposit(int)
func Withdraw(int)
}
英文:
The result of the method expression AccountService.Open
is a function with with type func(AccountService, string, string, time.Time) AccountService
. The code is missing the first argument. You can call it like this:
aliceAcct := AccountService.Open(CheckingAccount{}, "12345", "Alice", time.Date(1999, time.January, 03, 0, 0, 0, 0, time.UTC))
If you have no meaningful value to use as the receiver, then use a function instead:
func OpenCheckingAccount(no string, name string, openingDate time.Time) AccountService {
...
}
If you need to abstract account creation, then define the service as a function:
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 { ... }
The OpenSavings
and OpenChecking
functions can be used as an AccountService.
You will want to use different types for the service and accounts. Here, I use AccountService and AccountType. AccountType is not a very good name, but Account is already used. AccountType might be defined as the following:
type AccountType interface {
func Deposit(int)
func Withdraw(int)
}
答案2
得分: 4
尝试这样做:
acct := SavingsAccount{}
aliceAcct := acct.Open("12345", "Alice", time.Date(1999, time.January, 03, 0, 0, 0, 0, time.UTC))
fmt.Println("Alice的账户 =", aliceAcct)
你需要创建一个正确实现AccountService接口的结构体实例。
--编辑
工作示例:play.golang.org
英文:
Try this
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)
You need to create an instance of a struct that properly implements the AccountService interface
--Edit
Working example: play.golang.org
答案3
得分: 2
大多数Go包都会执行以下两种操作之一:
-
在包级别定义一个名为
OpenSavingsAccount
的函数,该函数返回一个打开且初始化的SavingsAccount。 -
在包中定义一个名为
DefaultSavingsAccount
的默认变量,并在包级别上复制SavingsAccount的方法,这样它们就可以在DefaultSavingsAccount上进行操作。这会导致很多函数的重复,但所有的逻辑都保留在方法中。如果DefaultSavingsAccount不是常量且是一个接口类型,它可以被替换为另一个实现。
英文:
Most Go packages do one of two things:
-
Have a package level function such as
OpenSavingsAccount
that returns an open, initialized SavingsAccount. -
Have a default variable in the package named
DefaultSavingsAccount
and duplicate the SavingsAccount methods at the package level where they operate on the DefaultSavingsAccount. This is a lot of function duplication but all of the logic stays in the methods. And if the DefaultSavingsAccount is not const and is an interface type it can be replaced with another implementation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论