Go 何时对基本类型使用类型定义

Go 何时对基本类型使用类型定义,go,type-definition,Go,Type Definition,我的问题是关于Go中的类型定义以及何时将其用于基本类型。 请考虑下面的例子。 我有一个表示数据库中一行的结构: type DBEntityAttribute struct { Id uint64 EntityId uint64 EndPointNumber uint8 AttributeNumber uint8 ParentId uint64 Value string

我的问题是关于Go中的类型定义以及何时将其用于基本类型。
请考虑下面的例子。 我有一个表示数据库中一行的结构:

type DBEntityAttribute struct {
    Id              uint64
    EntityId        uint64
    EndPointNumber  uint8
    AttributeNumber uint8
    ParentId        uint64
    Value           string
    Tag             int
    ContentType     sql.NullString
    Maturity        int
    Author          int
    AttributeType   string
    IsNegated       bool
}
EntityId和AttributeEnumber是我在代码中的许多其他结构中使用的属性。
现在我想把它重构成这样:

type EntityId uint64

type AttributeNumber uint8

type DBEntityAttribute struct {
        Id              uint64
        EntityId        EntityId
        EndPointNumber  uint8
        AttributeNumber AttributeNumber
        ParentId        uint64
        Value           string
        Tag             int
        ContentType     sql.NullString
        Maturity        int
        Author          int
        AttributeType   string
        IsNegated       bool
    }
这将允许我在一个地方更改EntityId和AttributeEnumber的类型。另外,例如,当我将entityId作为函数参数传递时,我现在可以为它指定特定的entityId类型,而不是匿名uint64

我现在的问题是:

  • 这被认为是好的围棋代码吗
  • 我应该在哪里停止,这意味着我应该为代码中其他地方使用的每个属性声明一个不同的类型吗?还是只针对重要的

我知道这可能是主观的,但Go社区通常同意某些模式,我希望遵守他们的指导原则。

关于何时使用自定义类型,没有硬性规定。我个人的原则是:

有原因时使用自定义类型。 您希望在单个位置更改基础类型的原因似乎是一个很好的理由

其他好的理由是:

  • 分配自定义JSON(un)封送拆收器或其他接口方法
  • 作为文件
  • 与常量一起用作枚举
  • 改进了类型安全性(避免意外地将
    FooID
    分配给
    BarID

    • 关于何时使用自定义类型,没有硬性规定。我个人的原则是:

      有原因时使用自定义类型。 您希望在单个位置更改基础类型的原因似乎是一个很好的理由

      其他好的理由是:

      • 分配自定义JSON(un)封送拆收器或其他接口方法
      • 作为文件
      • 与常量一起用作枚举
      • 改进了类型安全性(避免意外地将
        FooID
        分配给
        BarID

      这些都是广泛的问题:是的,这不是不合理的。若EntityId和属性号可以获取方法,那个么这是非常合理的。当它没有意义时停止。字符串是字符串,整数是整数。不要陷入“但如果有一天我想改变它怎么办?”的陷阱。首先,你不会做出大多数改变;其次,在围棋中改变很简单。这些是广泛的问题:是的,这不是不合理的。若EntityId和属性号可以获取方法,那个么这是非常合理的。当它没有意义时停止。字符串是字符串,整数是整数。不要陷入“但如果有一天我想改变它怎么办?”的陷阱。首先,您不会进行大多数更改;其次,在Go中进行更改很简单。特别是您的第二点(作为文档)是我所想到的,因为我有很多类型都具有相同的类型(例如uint64),但含义完全不同。有时,这些属性被用作映射中的键,当您在代码中的不同位置使用它们时,这会使它更容易混淆,以避免混淆和错误,例如如果您有一个函数,否则它将接受3个uint64参数,所有这些参数都是ID。是的。到目前为止,我的文档都是为参数提供非常描述性的名称,如entityId uint64、databaseId uint64等。。。有了类型定义,clearerIt就可以提供额外的类型安全性。如果不进行类型转换,则不能有
      a MyIDType
      b uint64
      以及
      c:=a+b
      。这有时有助于防止编译时出现简单错误(尽管它不能防止非类型常量文本的错误)。@Adrian:这确实是一个很好的观点。它使我更容易、更清楚地决定哪些类型应该获得自己定义的自定义类型。每次我有相同类型的属性,并且经常在相同的位置使用,并且可以很容易地切换(例如,一个方法需要参数id1 uint64和id2 uint64,但您意外地使用(id2,id1)调用该方法),这里的解决方案就是自定义类型,特别是您的第二点(作为文档)是我想到的,因为我有很多类型都有相同的类型(例如uint64),但意思完全不同。有时,这些属性被用作映射中的键,当您在代码中的不同位置使用它们时,这会使它更容易混淆,以避免混淆和错误,例如如果您有一个函数,否则它将接受3个uint64参数,所有这些参数都是ID。是的。到目前为止,我的文档都是为参数提供非常描述性的名称,如entityId uint64、databaseId uint64等。。。有了类型定义,clearerIt就可以提供额外的类型安全性。如果不进行类型转换,则不能有
      a MyIDType
      b uint64
      以及
      c:=a+b
      。这有时有助于防止编译时出现简单错误(尽管它不能防止非类型常量文本的错误)。@Adrian:这确实是一个很好的观点。它使我更容易、更清楚地决定哪些类型应该获得自己定义的自定义类型。每次我拥有的属性类型相同,并且经常在相同的位置使用,并且可以轻松切换(例如,一个方法需要参数id1 uint64和id2 uint64,但您意外地使用(id2,id1)调用该方法),这里的解决方案是自定义类型