【问题标题】:After renaming a type, I cannot access some of its methods重命名类型后,我无法访问它的某些方法
【发布时间】:2015-11-14 13:02:31
【问题描述】:

为了防止在我的项目的不同文件中存在多个依赖关系,并且由于我可能会更改数据的呈现方式,我决定为 @ 987654321@

因为我不需要其他任何东西,所以我只是重命名了其中一种类型:

type CanvasContext draw2dimg.GraphicContext

在我的一个模块中,我有以下代码(路径是 CanvasContext 变量):

// initialization and some code omitted for clarity
path.SetFillColor(color.RGBA{0x44, 0xff, 0x44, 0xff})
path.SetStrokeColor(color.RGBA{0x44, 0x44, 0x44, 0xff})
path.SetLineWidth(5)
// some more code here
path.Close()
path.FillStroke()

在所有路径上的方法调用中,只有 FillStroke 因编译错误而失败:

path.FillStroke 未定义(类型 *drawing.CanvasContext 没有字段或 方法 FillStroke)

为了防止它,我必须重新定义 FillStroke,但不是任何其他方法,使用:

func (cc *CanvasContext) FillStroke() {
    gc := draw2dimg.GraphicContext(*cc)
    gc.FillStroke()
}

为什么我必须只重新定义那个调用,而不需要重新定义任何其他调用?

【问题讨论】:

  • draw2dimg 包将类型 GraphicContext 定义为嵌入另一种实现大多数这些方法的类型。但是,FillStroke 方法仅在GraphicContext 上直接实现。如果您使用嵌入,它将按您预期的那样工作,否则不会。见this simplified example。 (即type Foo Bar not 是否使Bar 的方法可用,为此使用嵌入)。
  • 虽然我仍然不知道该决定背后的原因,但我可以通过您的示例看到我的代码有什么问题。如果您回答问题(而不是评论),我会将您的回答标记为有效:D

标签: methods types go


【解决方案1】:

您应该使用结构嵌入而不是类型定义。检查结构'embedding'文档:

但随后要推广领域的方法并满足 io 接口,我们还需要提供转发方法,比如 这个:

func (rw *ReadWriter) Read(p []byte) (n int, err error) { 返回 rw.reader.Read(p) }

通过直接嵌入结构,我们避免了这种簿记。

【讨论】:

    猜你喜欢
    • 2015-05-16
    • 2010-09-14
    • 2015-07-28
    • 2021-09-18
    • 2022-12-21
    • 2019-09-09
    • 2012-06-03
    • 1970-01-01
    相关资源
    最近更新 更多