在golang中使用自己类型的最佳实践。 Alians建造类型

时间:2016-10-26 17:08:47

标签: go types

我想知道何时或是否应该在golang中使用自己的类型。如果这对我的代码更加友好,或者我不应该使用自己的类型。

实施例: 我想使用 MAC 创建map类型,命名主机

以第一种方式最简单的我可以做到

var machines map[string]string{
   "11:22...": "myHost",
   "22:33..":  "yourHost",
}

以第二种方式

type MAC string
type HOST string

  machines := map[MAC]HOST{
       MAC("11:22..") : HOST("myHost"),
       MAC("22:33..") : HOST("yourHost"),
    }

在上面的例子中,我可以对我的类型MAC进行额外的控制,HOST使用写入方法进行验证,比较等更好吗?

第三种方式

type MACHINES map[string]string

m := MACHINES{}
    m = map[string]string{
     "11:22.." : "myHost",
     "22:33" : "yourHost",
    }

上面的例子对我来说最难理解的是其他人不太直观。我认为上面的例子也应该填写HOST和MAC因为类型MACHINE没什么好说开发人员应该如何实现所以我想

  type MACHINES map[MAC]HOST

但是,关于更好地了解golang中的用法自己的类型,请关于评语。

5 个答案:

答案 0 :(得分:3)

如果没有评论您的具体示例,您通常会想要使用新类型的原因有几个:

  • 您需要在类型
  • 上定义方法
  • 您不希望该类型与文字或变量具有从中派生的类型(例如,减少用户混淆或确保它们不会执行无效操作,例如尝试将您的特殊字符串与其他字符串进行比较)随机字符串)
  • 您只需要一个放置文档的位置,或者对返回特定类型的方法进行分组(例如,如果您有几个返回net.Conn的Dial方法,则可以创建type Conn net.Conn并返回而只是为了在godoc中对Conn类型头下的函数进行分组,或者为方法返回的net.Conn提供一般文档。
  • 因为您希望人们能够检查您的包装中是否有某种类型的通用类型(例如,即使您的Conn只是一个普通的net.Conn,它也可以选择类型切换和检查是否这是一个yourpackage.Conn)
  • 您希望函数从预定义的事物列表中获取参数,并且您不希望用户能够创建可以传入的新值(例如,未导出类型的导出常量列表)

答案 1 :(得分:0)

Go的一个最重要的功能是接口。在Go中,通过定义接口的方法来实现接口,实现接口的唯一方法是在类型中添加一个Method。例如,假设您要从fmt包中实现Stringer接口。

在您的示例type MACHINES map[string]string中,您需要为您的类型添加名为String的方法。

func (m MACHINES) String() string {
    s := "MACHINES\n"
    for k, v := range m {
        s += fmt.Sprintf("%v: %v\n", k, v)
    }
    return s
}

接受Stringer接口的任何其他函数现在也可以接受您的MACHINES类型,因为您实现了Stringer接口。

例如,fmt.Printf检查传入的类型是否实现Stringer接口

m := MACHINES{"foo":"bar", "baz": "bust"}
fmt.Printf("%s", m)

将调用MACHINES String方法

playground

中的示例

答案 2 :(得分:0)

创建类型别名仅在需要添加额外方法(例如验证函数)或者想要记录某些值的所需用途时才有用(例如,net.IP类型)。

类型别名可以帮助您防止API误解,但如果您使用常量值则不会。例如,此代码有效:

type Host string
type Mac string
hosts := map[Mac]Host{"ad:cb..": "localhost"}

有关常量如何在Go中工作的更多信息,您可以查看Rob Pike's blog post

答案 3 :(得分:0)

在我看来,你确实想要使用自己的类型。

作为一个例子,函数参数列表都是" string"或者全部" int"令人困惑,很容易出错。

并对您的类型名称发表评论。 " MAC"是Media Access Control的首字母缩写,所以它应该保持全部大写。但是" HOST"应该是"主持人"因为它只是一个字。我不记得它究竟在哪里,但是Go名称的推荐形式是CamelCase,包含全部缩写,例如" GetIPv4AddressFromDNS"

答案 4 :(得分:0)

我认为使用你自己的类型的另一个原因,这里没有提到,如果你不确定什么是正确的类型,例如uint8 / uint16,你想稍后在一个地方轻松改变它。

但是,只要您想使用内置类型的方法,就可以进行转换。或者您需要在自己的类型上定义它们。