【问题标题】:Manipulate struct field when using interface使用接口时操作结构字段
【发布时间】:2017-12-28 15:51:57
【问题描述】:

标题可能具有误导性,但切中要害……

我只有一个接口Expression

type Expression interface {
    String() // skiped in implementation below
}

接口由多个结构体实现,其中一些实现了与字段值相同的接口:

type IdentExpression struct {
    value string
}

type UnaryExpression struct {
    token string
    value Expression
}

func (a *UnaryExpression) Simplify() {
    var finalValue Expression
    switch a.value.(type) {
    case UnaryExpression:
        tmp := a.value.(UnaryExpression)
        switch tmp.value.(type) {
        case UnaryExpression:
            tmp = tmp.value.(UnaryExpression)
            finalValue = tmp.value
        }
    }

    a.value = finalValue
}

给定表达式-(-(-(1)))UnaryExpression.Simplify() 会将表达式简化为-(1)。 (play)

我想用Simplify()方法扩展接口:

type Expression interface {
    Simplify()
    String() string
}

// ...

func (a IdentExpression) Simplify() {} // do nothing

结果代码不起作用(play):

main.go:29: 不可能的类型切换案例:a.value(表达式类型)不能有动态类型 UnaryExpression(缺少 Simplify 方法)

main.go:30: 不可能的类型断言:

UnaryExpression does not implement Expression (Simplify method has pointer receiver)

main.go:59:不能在字段值中使用 UnaryExpression 文字(类型 UnaryExpression)作为类型表达式:

UnaryExpression does not implement Expression (Simplify method has pointer receiver)

main.go:60:不能使用 UnaryExpression 文字(类型 UnaryExpression)作为字段值中的类型表达式:

UnaryExpression does not implement Expression (Simplify method has pointer receiver)

我找到了this answer,看起来很相似,但是我不知道如何在我的情况下应用它。

【问题讨论】:

  • 删除 Simplify 函数中的指针引用。您的代码应该可以工作。

标签: pointers go struct interface


【解决方案1】:

这里的关键是您在Simplify() 的定义中使用了指针接收器,相对于UnaryExpression

func (a *UnaryExpression) Simplify()

您正在实现的其他方法不使用指针接收器:

// One example
func (a IdentExpression) Simplify() {}

通常,在 Go 中,最好的做法是让同一类型的所有方法使用相同类型的接收器(即,如果一个方法使用指针接收器,它们都应该。同样,如果一个方法使用非指针接收器,它们都应该针对该特定类型)。

在这种情况下,如果您从UnaryExpressionSimplify 方法中删除指针接收器,则代码将编译。希望这会有所帮助!

编辑:Here is a more comprehensive answer that explains exactly why this error happens, it's really a good read.

【讨论】:

  • 如果我删除指针,代码编译,但不工作:) 尽管如此,你的答案和你链接的答案一起帮助我找到问题 - 我需要将我所有的断言替换为指针( here's the fixed code)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多