go:调用接口上的方法会创建新副本作为类型断言的一部分,需要断言指针的类型才能从指针调用方法

问题描述 投票:0回答:1

所以我已经为看板实现了这个结构,这里有一些与问题相关的内容:

type Menu struct {
    Projects dll.DLL
}

type Project struct {
    Title  string
    Lists  dll.DLL
    Labels dll.DLL
}

type List struct {
    Title string
    Cards dll.DLL
}

func StartMenu() *Menu {
    return &Menu{
        Projects: dll.New(),
    }
}

func (m *Menu) AddProject(title string) {
    project := Project{
        Title: title,
        Lists: dll.New(),
    }
    m.Projects.Append(project)
}

func (p *Project) AddList(title string) {
    list := List{
        Title: title,
        Cards: dll.New(),
    }
    p.Lists.Append(list)
}

现在 dll.DLL 是我创建的一个帮助程序包,用于抽象数据结构的使用,在本例中是一个双向链表:此处实现 因为我想抽象它,所以节点中的值都是接口,似乎是最好的方法。

因此创建一些模拟数据来检查它是否正常工作,令人惊讶的是,事实并非如此

menu := kanban.StartMenu()
menu.AddProject("project1")
project1, err := menu.Projects.WalkTo(0)
if err != nil {
    log.Println(err)
}
project1Val := project1.GetVal().(kanban.Project)
project1Val.AddList("List 1")

那是因为

project1.GetVal().(kanban.Project)
为我提供了项目的副本,因此当调用
project1Val.AddList("List 1")
时,它会影响副本而不是原始版本,这方面没有什么新内容,正常行为。

所以我为

dll.Node
GetValPtr()
添加了一个新方法,它返回指向节点值的指针,因为
Node.Val
是一个接口,它返回
*interface{}
,这是棘手的部分:
我无法断言
*interface{}
的类型,因为它不是
interface{}
,这是有道理的,指针不是问题,但是我应该能够断言该指针的基础类型,并在断言后使用它是说类型,但我想到的唯一方法是取消引用指针,然后断言类型,这将给我与上面代码中相同的内容,只是需要额外的步骤。再次,值的副本。

project1Val := project1.GetValPtr()
proj1 := (*project1Val).(kanban.Project)
proj1.AddList("List 1")

有没有办法断言指针的基础类型,以便在原始对象而不是副本上使用该方法?

go pointers methods interface
1个回答
0
投票

所以我解决了它,我认为这部分是@BurakSerdar试图在评论中告诉我的,但我对它的理解不同。谢谢你,在你眼里这很简单,现在对我来说也很简单,即使我必须绕很远的路才能到达那里。

基本上我在创建对象时开始附加指针而不是值:

func (m *Menu) AddProject(title string) {
    project := &Project{
        Title: title,
        Lists: dll.New(),
    }
    m.Projects.Append(project)
}

func (p *Project) AddList(title string) {
    list := &List{
        Title: title,
        Cards: dll.New(),
    }
    p.Lists.Append(list)
}

并检索指向该值的指针,这正是我想要的

project1Val := project1.GetVal().(*kanban.Project)

它有效,没有错误,这是输出:

projects:
- title: project1
  lists:
  - title: List 1
    cards:
    - title: Card 1
      description: ""
      checklist: []
      card_labels: []
    - title: Card 2
      description: ""
      checklist: []
      card_labels: []
  - title: List 2
    cards:
    - title: Card 1
      description: ""
      checklist: []
      card_labels: []
    - title: Card 2
      description: ""
      checklist: []
      card_labels: []
  labels:
  - title: Label 1
    color: "30"
  - title: Label 2
    color: "50"
- title: project2
  lists:
  - title: List 1
    cards:
    - title: Card 1
      description: ""
      checklist: []
      card_labels: []
    - title: Card 2
      description: ""
      checklist: []
      card_labels: []
  - title: List 2
    cards:
    - title: Card 1
      description: ""
      checklist: []
      card_labels: []
    - title: Card 2
      description: ""
      checklist: []
      card_labels: []
  labels:
  - title: Label 1
    color: "30"
  - title: Label 2
    color: "50"
© www.soinside.com 2019 - 2024. All rights reserved.