An enumeration type in the Go language

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

An enumeration type in the Go language

2017-03-06

Enumeration types are most natural to write in ML languages such as ocaml,f#:

type T = | T1 of int | T2 of string| T3 of bool

Haskell seems to use the datetype instead of the type and doesn't remember the details. In short, this is a very important type and is not limited to functional languages.

In the C language, there is no guarantee of type safety. Fortunately, C has a union type, and there is a pointer, this thing is too flexible, can play to fly. In C The enumeration type can be written like this:

struct T {  int kind;  union {    char* T1;    int T2;    bool T3;  } value;};

Here's a small detail, the size of the Union is equal to the largest one in the structure, so this is not necessarily the best notation. C is flexible enough to say no more.

In go, even the Union keyword is not, the type is also more stringent, the pointer is not as easy as C can go. It is possible to compare the standard practice with interface. Interface can also fly, for example, this article has been explored before. But now it's too complicated to think back.

interface{} like a pointer to C, it can be of any type. But there are some problems, the first problem, its type of security is determined by the runtime, compared to the functional language only produces compile-time overhead, but also less than a lot.

Another problem is that the code is a neat person, in fact, as long as the code to write:

if _, ok := t.(T); ok {}

I think the basic is bad smell. The go language relies on interfaces rather than implementations (in principle any language is), you use interfaces, and you need to reflect concrete implementations that are ugly.

One more important question, of course, is performance. Parameter passing has an object assignment, and the original value is reflected with interface and the object is assigned. That whether you are

func f(v interface{}) {}f(3) // 由于参数是interface,这里会分配一个interface对象,对象的值指向3

Still is

raw, ok := t.(T)   // raw不是原始值,而是分配一个T并从原始值拷贝。

There is a memory allocation overhead. In some performance-critical situations, this overhead is still quite harmful to GC.

Anyway, it's not an elegant scheme to implement enum types in go with interface.

Here's what I think is a better way to do it.

Define the embedded class first:

type T struct {    kind enumT}

This type is embedded in the implementation of the T1 T2 T3 that you want to enumerate:

type T1 struct {    T    v int}type T2 struct {    T    v string}type T3 struct {    T    v bool}

When actually used, our type is to *T judge kind to know the real type:

var t *Tswitch t.kind {case kindT1:case kindT2:default:}

To create an object of the herding type:

var t *Ttmp := T1{}tmp.kind = kindT1t = &tmp.T

Of course, it's best to encapsulate the function

func createT1() *Tfunc createT2() *Tfunc createT3() *T

You can make an alias for the type of kind, and define constants:

type enumT intconst (    kindT1 enumT = iota    kindT2    kindT3)

Using an enumeration to *T reflect a real type *T1 requires a pointer conversion, and with unsafe, you can actually use a function to seal it up:

var t Traw := (*T1)(unsafe.Pointer(t))

This notation is no more expensive than using interface, and is safe for GC (with unsafe). It is not safe to keep things pointer.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.