为什么要基于其他类型创建go类型?

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

Why create go types based on other?

问题

定义新类型的目的是什么:

type NewType OldType

由于NewType只有方法声明,所以:

var x NewType

也可以存储OldType的“对象”。这样做有什么优势吗?

英文:

what is the purpose of defining new types in go:

type NewType OldType

since NewType have only methods declarations, so:

var x NewType

can store also OldType 'objects'. Are there any advantages?

答案1

得分: 5

一般来说,给类型命名的原因非常简单,大多数语言都是一样的 - 可以给复杂的类型命名,比如:

<!-- language: golang -->

type Person struct{
    name String
    age  uint8
}

然而,像你描述的这样命名类型,我称之为“类型别名”(不确定其他人是否使用这个术语,但这是我常用的术语),并没有给你上述提到的优势。然而,它确实给你提供了一种在现有类型上添加方法的能力。Go不允许你在你没有自己定义的现有类型上添加方法(即内置类型或在其他包中定义的类型),所以类型别名允许你假装你自己定义了它们,并且因此可以在它们上添加方法。另一种很好的思考方式是,它类似于在面向对象的语言(比如Java)中创建包装类型的更简洁版本。

所以,假设我想将整数用作错误。在Go中,error接口只需要一个名为“Error”的方法,该方法返回一个字符串。使用类型别名,我可以这样做:

<!-- language: golang -->

type errorCode int

func (e errorCode) Error() string {
    return fmt.Sprintf("%d", e)
}

...然后我可以使用整数错误码。相比之下,如果我尝试以下操作,将会出错:

<!-- language: golang -->

func (e int) Error() string {
    return fmt.Sprintf("%d", e)
}

为了演示,请查看这个实现:
http://play.golang.org/p/9NO6Lcdsbq

只是为了澄清(因为我使用“别名”这个词可能会误导),在其他方面等效的两种类型(例如上面示例中的interrorCode)是不能互换的。Go类型系统将它们视为根本不同的类型,尽管你可能能够在它们之间进行类型转换。

英文:

The reason behind naming types in general is fairly straightforward, and is much the same in most languages - being able to name complex types, like:

<!-- language: golang -->

type Person struct{
    name String
    age  uint8
}

However, naming a type like you described, which I'll call "type aliasing" (not sure if this is used by anyone else, but it's the term I tend to use), doesn't give you the above-mentioned advantage. What it <i>does</i> give you, however, is the ability to add methods to existing types. Go disallows you from adding methods to existing types that you did not define yourself (ie, built-in types or types defined in other packages), so aliasing allows you to pretend that you <i>did</i> define them yourself, and thus add methods to them. Another good way to think about it is like a much more concise version of creating a wrapper type (as you would in an OO language like Java, for example).

So, let's say that I wanted to be able use integers as errors. In Go, the error interface simply requires a method called "Error" which returns a string. Using type aliasing, I could do:

<!-- language: golang -->

type errorCode int

func (e errorCode) Error() string {
    return fmt.Sprintf(&quot;%d&quot;, e)
}

...and I could use integer error codes. By contrast, if I tried the following, I would get an error:

<!-- language: golang -->

func (e int) Error() string {
    return fmt.Sprintf(&quot;%d&quot;, e)
}

To demonstrate, check out this implementation:
http://play.golang.org/p/9NO6Lcdsbq

Just to clarify (because my use of the word "alias" may be misleading), two types which are otherwise equivalent (for example, int and errorCode in the above example) are not interchangeable. The Go type system treats them as fundamentally different types, although you may be able to type-cast between them.

答案2

得分: 3

要识别一组特定的值和操作。

例如,

package main

import "fmt"

type Coordinate float64

type Point struct {
    x, y Coordinate
}

func (p *Point) Move(dx, dy Coordinate) {
    p.x += dx
    p.y += dy
}

func main() {
    var p = Point{3.14159, 2.718}
    fmt.Println(p)
    p.Move(-1, +1)
    fmt.Println(p)
}

输出:

{3.14159 2.718}
{2.14159 3.718}
英文:

> The Go Programming Language Specification
>
> Types
>
> A type determines the set of values and operations specific to values
> of that type.

You want identify a specific set of values and operations.

For example,

package main

import &quot;fmt&quot;

type Coordinate float64

type Point struct {
	x, y Coordinate
}

func (p *Point) Move(dx, dy Coordinate) {
	p.x += dx
	p.y += dy
}

func main() {
	var p = Point{3.14159, 2.718}
	fmt.Println(p)
	p.Move(-1, +1)
	fmt.Println(p)
}

Output:

{3.14159 2.718}
{2.14159 3.718}

huangapple
  • 本文由 发表于 2013年7月4日 01:54:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/17454993.html
匿名

发表评论

匿名网友

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

确定