Golang中如何从一个结构体方法访问另一个结构体的方法
Golang中如何从一个结构体方法访问另一个结构体的方法 你好,
我希望从一个结构体的方法(Operator.OperateThis/OperateThat)内部访问另一个结构体的方法(Service.DoThis/DoThat)。通过将 Service 注入到 Operator 中可以轻松实现,这也是我目前的做法,但我想避免这样做——请参考下面的简单示例。我只是不想在 Operator 中看到 Service 结构体。这可能吗?如果可以,最优雅/最简洁的方法是什么?
理想情况下,我不想向 Operator 中注入任何东西。但是,我可以接受注入除 Service 之外的任何东西。我研究过将变量/类型作为函数,但没有进展。这里的关键点是,Service 只被实例化一次,我想保留它的引用。
谢谢
main.go
package main
import "log"
func main() {
operator := &Operator{}
StartService(operator)
if err := operator.OperateThis(); err != nil {
log.Fatalln(err)
}
if err := operator.OperateThat(); err != nil {
log.Fatalln(err)
}
}
connection.go
package main
type Connection struct {
// ...
}
// ...
service.go
package main
type Service struct {
connection *Connection
// ...
}
func StartService(operator *Operator) {
// ...
operator.SetService(&Service{})
// ...
}
func (s *Service) DoThis() error {
s.obtainConnection()
// ...
return nil
}
func (s *Service) DoThat() error {
s.obtainConnection()
// ...
return nil
}
// ...
func (s *Service) obtainConnection() {
s.connection = &Connection{}
}
operator.go
package main
import "log"
type Operator struct {
service *Service
}
func (o *Operator) SetService(service *Service) {
o.service = service
}
func (o *Operator) OperateThis() error {
if err := o.service.DoThis(); err != nil {
log.Fatalln(err)
}
log.Println("operated this")
return nil
}
func (o *Operator) OperateThat() error {
if err := o.service.DoThat(); err != nil {
log.Fatalln(err)
}
log.Println("operated that")
return nil
}
更多关于Golang中如何从一个结构体方法访问另一个结构体的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
如果你通过函数来改变结构体的字段,可以使用接口来隐藏你想要隐藏的部分。
type Operator interface {
OperateThis() error
OperateThat() error
}
type Service struct {
operator Operator
// ...
}
func StartService(operator Operator) {
// ...
operator.SetService(&Service{})
// ...
}
另一个问题是这些结构体之间的耦合非常紧密。Service 知道 operator,而 operator 也知道 Service。我认为这是你遇到问题的根本原因。
可以通过接口来解耦,这样Operator就不需要直接依赖Service结构体。定义一个Service接口,然后让Operator持有该接口类型:
package main
import "log"
// 定义Service接口
type Service interface {
DoThis() error
DoThat() error
}
type Operator struct {
service Service // 改为接口类型
}
func (o *Operator) SetService(service Service) {
o.service = service
}
func (o *Operator) OperateThis() error {
if err := o.service.DoThis(); err != nil {
log.Fatalln(err)
}
log.Println("operated this")
return nil
}
func (o *Operator) OperateThat() error {
if err := o.service.DoThat(); err != nil {
log.Fatalln(err)
}
log.Println("operated that")
return nil
}
Service结构体实现该接口:
package main
type ServiceImpl struct {
connection *Connection
}
func (s *ServiceImpl) DoThis() error {
s.obtainConnection()
// ...
return nil
}
func (s *ServiceImpl) DoThat() error {
s.obtainConnection()
// ...
return nil
}
func (s *ServiceImpl) obtainConnection() {
s.connection = &Connection{}
}
修改StartService函数:
func StartService(operator *Operator) {
operator.SetService(&ServiceImpl{})
}
这样Operator只依赖Service接口,不依赖具体的ServiceImpl结构体。如果需要进一步解耦,可以使用函数类型:
package main
import "log"
type Operator struct {
doThisFunc func() error
doThatFunc func() error
}
func (o *Operator) SetOperations(doThis, doThat func() error) {
o.doThisFunc = doThis
o.doThatFunc = doThat
}
func (o *Operator) OperateThis() error {
if err := o.doThisFunc(); err != nil {
log.Fatalln(err)
}
log.Println("operated this")
return nil
}
func (o *Operator) OperateThat() error {
if err := o.doThatFunc(); err != nil {
log.Fatalln(err)
}
log.Println("operated that")
return nil
}
初始化时注入函数:
func StartService(operator *Operator) {
service := &Service{}
operator.SetOperations(service.DoThis, service.DoThat)
}


