2013-01-20 8 views
315

Her biri yalnızca {A, C, T, G}'dan biri olabilen N bazından oluşan basitleştirilmiş bir kromozomu temsil etmeye çalışıyorum.Git'te enumları temsil etmenin deyimsel bir yolu nedir?

Kısıtlamaları bir enum ile resmileştirmek istiyorum, ancak bir enum'u taklit etmenin en çılgın yolunun Go'da neler olduğunu merak ediyorum.

+3

türünü kontrol etmelidir. Http://golang.org/pkg/os/#pkg-constants –

+2

ile ilgili: http: // stackoverflow.com/questions/14236263/ne zaman yapılmalı ne zaman-bir-yap-türü-başka-tip-ve-ne-it-it-sadece- – lbonn

+0

[Golang: Sabit Tip oluşturma ve Kısıtlama Türün Değerleri] (http://stackoverflow.com/questions/37385007/golang-creating-a-constant-type-and-restricting-the-types-values) – icza

cevap

443

dil özellikleri alıntı: Iota

sabit bir beyan içinde, predeclared tanımlayıcı iyota ardışık Türlenmemiş tamsayı sabitleri temsil eder. Her bir ConstSpec'ten sonra rezerve sözcük yapısı kaynakta görüntülendiğinde ve artımlarda 0'a sıfırlanır. Ilgili bir sabitler kümesi oluşturmak için kullanılabilir: yalnızca her ConstSpec sonra artırılır, çünkü bir Expressionlist içinde

const ( // iota is reset to 0 
     c0 = iota // c0 == 0 
     c1 = iota // c1 == 1 
     c2 = iota // c2 == 2 
) 

const (
     a = 1 << iota // a == 1 (iota has been reset) 
     b = 1 << iota // b == 2 
     c = 1 << iota // c == 4 
) 

const (
     u   = iota * 42 // u == 0  (untyped integer constant) 
     v float64 = iota * 42 // v == 42.0 (float64 constant) 
     w   = iota * 42 // w == 84 (untyped integer constant) 
) 

const x = iota // x == 0 (iota has been reset) 
const y = iota // y == 0 (iota has been reset) 

, her bir zerre değeri aynıdır:

const (
     bit0, mask0 = 1 << iota, 1<<iota - 1 // bit0 == 1, mask0 == 0 
     bit1, mask1       // bit1 == 2, mask1 == 1 
     _, _         // skips iota == 2 
     bit3, mask3       // bit3 == 8, mask3 == 7 
) 

Bu son örnek, son boş olmayan ifade listesinin örtük tekrarını kullanır. Eğer bazlar int ayrı bir tip olmasını istiyorsanız


Yani kod

const (
     A = iota 
     C 
     T 
     G 
) 

veya

type Base int 

const (
     A Base = iota 
     C 
     T 
     G 
) 

gibi olabilir.

+11

harika örnekler (Tam olarak iota davranışını hatırlamadım - artırıldığında - özellikten). Şahsen ben bir türüne bir tür vermek istiyorum, bu yüzden argüman, alan, vb. Olarak kullanıldığında tip kontrol edilebilir. – mna

+9

Çok ilginç @jnml. Ama ben statik tip kontrolünün gevşek gibi göründüğü için hayal kırıklığına uğramışımdır, örneğin, hiç bir zaman benim var olmadığım Base 42'yi kullanmamı engelleyemez: http://play.golang.org/p/oH7eiXBxhR – Deleplace

+3

Git hiçbir kavramı yoktur örneğin sayısal alt türlerden Pascal'ın, yani 'Ord (Base)' '0..3' ile sınırlı değil, aynı zamanda altta yatan sayısal türü ile aynı limitleri vardır. Bir dil tasarımı seçimi, güvenlik ve performans arasında uzlaşma. Bir "Base" yazılan değerine dokunduğunuzda "güvenli" çalışma zamanı bağlı kontrolleri her zaman düşünün. Veya aritmetik ve "++" ve "-" için "Baz" değerinin 'taşma' davranışını nasıl tanımlamalıdır? Etc. – zzzz

57

jnml'nin yanıtına bakarak, Base türünü hiç dışa aktarmadan (yani, küçük harfle yazarak) Base örneğinin yeni örneklerini önleyebilirsiniz. Gerekirse, bu arayüz Üs başa dışarıdan fonksiyonlarda kullanılabilir, böylece bir taban türünü döndüren bir yöntem olan verilebilir bir arayüz yapmak yani edebilir

package a 

type base int 

const (
    A base = iota 
    C 
    T 
    G 
) 


type Baser interface { 
    Base() base 
} 

// every base must fullfill the Baser interface 
func(b base) Base() base { 
    return b 
} 


func(b base) OtherMethod() { 
} 

package main 

import "a" 

// func from the outside that handles a.base via a.Baser 
// since a.base is not exported, only exported bases that are created within package a may be used, like a.A, a.C, a.T. and a.G 
func HandleBasers(b a.Baser) { 
    base := b.Base() 
    base.OtherMethod() 
} 


// func from the outside that returns a.A or a.C, depending of condition 
func AorC(condition bool) a.Baser { 
    if condition { 
     return a.A 
    } 
    return a.C 
} 

Ana paketin içinde a.Baser şimdi bir enum gibi etkili. Sadece bir paketin içinde yeni örnekler tanımlayabilirsiniz.

+7

Yönteminiz, "base" işlevinin yalnızca yöntem alıcısı olarak kullanıldığı durumlar için mükemmel görünüyor. Eğer 'a' paketiniz' base' türünde bir parametre alan bir işlev ortaya çıkarsa, tehlikeli olur. Gerçekten de, kullanıcı onu, bir int'ye gönderilebileceğinden, fonksiyonun "base" olarak kabul edeceği, 42 nolu literal değeriyle söyleyebilirdi. Bunu önlemek için, 'base' bir' struct': 'tür temel yapı {value: int} 'yapınız. Sorun: Artık bazları sabit olarak bildiremezsiniz, sadece modül değişkenleri. Fakat 42 asla bu türden bir “üs” a dönüştürülmeyecek. – Niriel

+1

@metakeule Örneğinizi anlamaya çalışıyorum ama değişken isimlerdeki seçiminiz onu son derece zorlaştırdı. – anon58192932

13

Go 1.4'ten itibaren,aracınızla birlikte enumunuzu kolayca hata ayıklama ve yazdırılabilir hale getiren komutla birlikte tanıtılmıştır.

1

Sen o kadar yapabilirsiniz:

type MessageType int32 

const (
    TEXT MessageType = 0 
    BINARY MessageType = 1 
) 

bu kod derleyici ile onlar sabitleri olarak temsil ediyoruz go standart ambalajlarda enum

+2

Sabitler genellikle normal büyüklükte değil, hepsi büyük harfle yazılır. İlk büyük harf, değişkenin dışa aktarılacağı anlamına gelir; bu, istediğiniz gibi olabilir veya olmayabilir. – 425nesp

+1

Go kaynak kodunda, bazen sabitlerin hepsinin büyük ve bazen de camelcase olduğu bir karışım var. Bir spesifikasyona referans var mı? –

+0

@JeremyGailor Sanırım 425nesp, normal tercihlerin geliştiricilerin _unexported_ sabitleri olarak kullanmaları için olduğunu ve bu nedenle de camelcase kullanacağını düşünüyorum. Geliştirici, dışa aktarılması gerektiğini belirlerse, önceden belirlenmiş bir tercih olmadığından tüm büyük harf veya büyük harf kullanımını kullanmaktan çekinmeyin. [Golang Code Review Önerileri] (https://github.com/golang/go/wiki/CodeReviewComments#mixed-caps) ve [Sabitler Üzerindeki Etkili Go Bölümü] 'ne bakın (https://golang.org/doc/ effective_go.html # constants) – waynethec