Go 使用指针和值接收器构造类型实例

Go 使用指针和值接收器构造类型实例,go,struct,interface,Go,Struct,Interface,让我们举一个非常小的例子,有一个函数可以修改结构中的值: package learn type Point struct { x int y int } func (p *Point) Set(x int, y int) { p.x = x p.y = y } 这可以正常工作,例如: package main import ( "NewPattern/learn" "fmt" ) func main() { p := learn.

让我们举一个非常小的例子,有一个函数可以修改结构中的值:

package learn

type Point struct {
    x int
    y int
}

func (p *Point) Set(x int, y int) {
    p.x = x
    p.y = y
}
这可以正常工作,例如:

package main

import (
    "NewPattern/learn"
    "fmt"
)

func main() {
    p := learn.Point{}
    p.Set(5, 6)
    fmt.Print(p)
}
它输出期望值:
{5,6}

现在假设我不希望用户拥有构造函数,我可以通过添加以下函数来更改代码:

func NewPoint(x int, y int) Point {
    return Point{x, y}
}
然后我可以在main中使用如下内容:

func main() {
    p := learn.NewPoint(3, 8)
    fmt.Print(p)
    p.Set(5, 6)
    fmt.Print(p)
}
它的工作原理与预期一样,返回
{38}{56}

现在,我们希望防止在不调用构造函数的情况下创建点-这里的情况并非如此,但对于复杂类来说可能有意义-因此,我们避免导出点,而是创建一个接口,因此我对代码进行了如下重构:(这不起作用!)

上面说:

cannot use point literal (type point) as type Point in return argument:
    point does not implement Point (Set method has pointer receiver)
我可以通过修改中的方法来“修复”此问题:

func NewPoint(x int, y int) point {
    return point{x, y}
}
但这只是移动了主要错误,即重构如下:

func main() {
    var p learn.Point
    p = learn.NewPoint(3, 8) //error here!
    fmt.Print(p)
    p.Set(5, 6)
    fmt.Print(p)
}
错误是:

cannot use learn.NewPoint(3, 8) (type learn.point) as type learn.Point in assignment:
    learn.point does not implement learn.Point (Set method has pointer receiver)
通过谷歌搜索,我成功地解决了以下问题:

func NewPoint(x int, y int) *point {
    return &point{x, y}
}
但是作为一个主要的结果,我们得到:&{38}&{56}作为一个印刷品,以及广告,我不知道幕后发生了什么


我想这与事物的传递和可能的“返回”有关,是这样吗?但是我不知道没有接口的第一个示例是如何不费吹灰之力就工作的。请有人澄清这些细节,我认为这些细节对理解非常重要。

点和
*点(即指向点的指针)是两种不同的类型。在您的代码中,
接口由
*点
类型实现。您可以将构造函数实现为:

func NewPoint(x int, y int) Point {
    return &point{x, y} 
}

打印将在点值之前显示
&
,因为基础值是指针。

*点
(即指向点的指针)是两种不同的类型。在您的代码中,
接口由
*点
类型实现。您可以将构造函数实现为:

func NewPoint(x int, y int) Point {
    return &point{x, y} 
}

打印将在点值之前显示
&
,因为基础值是指针。

“接口由*点而非点实现”可能是理解的关键。“接口由*点而非点实现”可能是理解的关键。