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

huangapple go评论73阅读模式
英文:

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

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)
}
英文:

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

playground example

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包都会执行以下两种操作之一:

  1. 在包级别定义一个名为OpenSavingsAccount的函数,该函数返回一个打开且初始化的SavingsAccount。

  2. 在包中定义一个名为DefaultSavingsAccount的默认变量,并在包级别上复制SavingsAccount的方法,这样它们就可以在DefaultSavingsAccount上进行操作。这会导致很多函数的重复,但所有的逻辑都保留在方法中。如果DefaultSavingsAccount不是常量且是一个接口类型,它可以被替换为另一个实现。

英文:

Most Go packages do one of two things:

  1. Have a package level function such as OpenSavingsAccount that returns an open, initialized SavingsAccount.

  2. 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.

huangapple
  • 本文由 发表于 2017年1月4日 10:31:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/41455324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定