Reputation: 80192
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)
}
Upvotes: 4
Views: 3591
Reputation: 121149
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)
}
Upvotes: 7
Reputation: 54383
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.
Upvotes: 2
Reputation: 6433
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
Upvotes: 4