私有类型具有导出字段

huangapple go评论104阅读模式
英文:

private type with exported fields

问题

在go教程的第二天中有这个练习:

为什么拥有一个具有导出字段的私有类型可能是有用的?

例如:

package geometry

type point struct {
    X, Y int;
    name string;
}

注意point是小写的,因此不是导出的,而X和Y字段是大写的,因此是导出的。在我看来,为了访问其中一个导出字段,你需要能够编写类似这样的代码。

p.X

但是为了使这个可能,p必须有一个类似这样的声明:

var p geomitry.point;

或者

p := new(geomitry.point);

然而,这是不可能的(据我所知),因为point的类型声明没有被导出。

英文:

In day 2 of the go tutorial there is this exercise:

Why may it be useful to have a private type with exported fields?

For example:

package geometry

type point struct {
    X, Y int;
    name string;
}

Notice that point is lowercase and thus not exported, whereas the fields X and Y are uppercase and thus are. It seems to me, that in order to have access to one of the exported fields, you would have to be able to write something like.

p.X

But in order for that to be possible, p would have to have a declaration like such:

var p geomitry.point;

or

p := new(geomitry.point);

This however is not possible (afaik), since the type declaration for point isn't exported.

答案1

得分: 20

但是你可以有一个公共构造函数,对吗?

所以如果你定义了一个NewGeometryPoint函数,那么你可能可以这样做(还没有对编译器进行测试):

p := NewGeometryPoint(640,480);
fmt.Println("X:",p.X, "Y:",p.Y);
英文:

But you could have a public constructor, right?

So if you had a <code>NewGeometryPoint</code> func defined, then you maybe could do (haven't tested against the compiler)

p := NewGeometryPoint(640,480);
fmt.Println(&quot;X:&quot;,p.X, &quot;Y:&quot;,p.Y);

答案2

得分: 10

一个抽象的基本类型?

package geometry

type point struct {
    X, Y int;
}

type Point struct {
    point;
    name string;
}

type Rect struct {
    P1, P2 point;
    name string;
}
英文:

An abstract base type ?

package geometry

type point struct {
    X, Y int;
}

type Point struct {
    point;
    name string;
}

type Rect struct {
    P1, P2 point;
    name string;
}

答案3

得分: 5

使用JSON包(http://golang.org/pkg/json/)时,您需要导出字段以将类型传递给json.Marshal(),但您可能不希望将该类型公开给其他外部包。

英文:

When using the JSON package (http://golang.org/pkg/json/). You need to have exported fields, to pass a type to json.Marshal(), but you might not want to have that type publicly available to other external packages.

答案4

得分: 2

这个相同的问题在这个Go课程中被提出为:

[...]你甚至可以有一个具有导出字段的私有类型。练习:那有什么用处?

如此呈现的话,你可以从外部访问作为包内部的元素,只是不能直接访问它。在你的例子中,对于结构体"point",这意味着你不能直接访问point的元素,如下所示:


// geometry.go

package geometry

type point struct {
    X, Y int
}

// main.go

package main

import (
    "fmt"    
    "./geometry"
)

func main() {
    point := geometry.point{
        X: 10,
        Y: 20
    }

    fmt.Printf("Point: %#v\n", point)
}

但是你可以使用定义的point来导出使用其导出的内部元素的元素,如下所示:


// geometry.go

package geometry

type point struct {
    X, Y int
}

//Vector ...
type Vector struct {
    Start point
    End   point
}

// main.go

package main

import (
    "fmt"

    "./geometry"
)

func main() {
    vector := geometry.Vector{}
    vector.Start.X = 10
    vector.Start.Y = 10
    vector.End.X = 10
    vector.End.Y = 10

    fmt.Printf("Vector: %#v\n", vector)
}

结果 -> Vector: geometry.Vector{Start:geometry.point{X:10, Y:10}, End:geometry.point{X:10, Y:10}}


所以,在我看来,这个机制旨在为您在声明内部数据结构时提供灵活性。

英文:

This same question is presented in this Go course as:

> [...]You may even have a private type with exported fields. Exercise:
> when is that useful?

As presented here you can access externally an element defined as internal to a package, you just can't access it directly. In the case of the structure "point" in your example, it means you CANNOT access elements of point directly, as in


// geometry.go

package geometry

type point struct {
    X, Y int
}

// main.go

package main

import (
    &quot;fmt&quot;    
    &quot;./geometry&quot;
)

func main() {
    point := geometry.point{
	    X: 10,
        Y: 20
    }

    fmt.Printf(&quot;Point: %#v\n&quot;, point)
}

But you CAN use the defined point to export elements that use its exported internal elements, as in


// geometry.go

package geometry

type point struct {
    X, Y int
}

//Vector ...
type Vector struct {
    Start point
    End   point
}

// main.go

package main

import (
	&quot;fmt&quot;

	&quot;./geometry&quot;
)

func main() {
	vector := geometry.Vector{}
	vector.Start.X = 10
	vector.Start.Y = 10
	vector.End.X = 10
	vector.End.Y = 10

	fmt.Printf(&quot;Vector: %#v\n&quot;, vector)
}

Result -> Vector: geometry.Vector{Start:geometry.point{X:10, Y:10}, End:geometry.point{X:10, Y:10}}


So, in my view, this mechanism is meant to give you flexibility in declaring internal data structures.

huangapple
  • 本文由 发表于 2009年11月21日 04:56:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/1773192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定