web-dev-qa-db-ja.com

インターフェイスの命名規則Golang

コードを投稿するだけです。

/*
*  Role will ALWAYS reserve the session key "role".
 */
package goserver

const (
    ROLE_KEY string = "role"
)

type Role string

//if index is higher or equal than role, will pass
type RolesHierarchy []Role

func (r Role) String() string {
    return string(r)
}

func NewRole(session ServerSession) Role {
    return session.GetValue(ROLE_KEY).(Role)
}

func (this Role) IsRole(role Role, hierarchy RolesHierarchy) bool {
    if role == this {
        return true
    }
    if len(hierarchy) == 0 {
        return false
    }
    var thisI int = 0
    var roleI int = 0
    //Duped roles in hierarchy are verified in verifyConfig during parse
    for i, r := range hierarchy {
        if this == r {
            thisI = i
        }
        if role == r {
            roleI = i
        }
    }
    //TODO I can probably condense what follows into one if
    if thisI == 0 && roleI == 0 {
        return false
    }
    return thisI >= roleI
}

func (this *Role) AssumeRole(session ServerSession, role Role) {
    session.SetValue(ROLE_KEY, role)
    *this = role
}

ServerSessionもインターフェイスであり、 "ServerSessioner"を呼び出すことは、私にとって不思議なことに注意する必要があります。

IsRole()とAssumeRole()でインターフェイスを作成するというアイデアをいじっていますが、「Roler」は非常に不安定です。標準の「er」接尾辞以外のインターフェースの命名規則を本当に知らないか、これまでに出くわしたことがないことに気付きました。 VS C++の慣習は、すべての前に「I」を投げるだけだということを思い出すようです。これは「イディオマティック」ですか?

助言がありますか?

15
Dale

私はそれを手に入れました。「er」の規則を使用できることがわかりました。

/*
*  Role will ALWAYS reserve the session key "role".
 */
package goserver

const (
    ROLE_KEY string = "role"
)

type Role string

//if index is higher or equal than role, will pass
type RolesHierarchy []Role

type RoleChecker interface {
    IsRole(Role, RolesHierarchy) bool
}

type RoleAssumer interface {
    AssumeRole(ServerSession, Role)
}

type RoleCheckerAssumer interface {
    RoleChecker
    RoleAssumer
}

func (r Role) String() string {
    return string(r)
}

func NewRole(session ServerSession) Role {
    return session.GetValue(ROLE_KEY).(Role)
}

func (this Role) IsRole(role Role, hierarchy RolesHierarchy) bool {
    if role == this {
        return true
    }
    if len(hierarchy) == 0 {
        return false
    }
    var thisI int = 0
    var roleI int = 0
    //Duped roles in hierarchy are verified in verifyConfig during parse
    for i, r := range hierarchy {
        if this == r {
            thisI = i
        }
        if role == r {
            roleI = i
        }
    }
    //TODO I can probably condense what follows into one if
    if thisI == 0 && roleI == 0 {
        return false
    }
    return thisI >= roleI
}

func (this *Role) AssumeRole(session ServerSession, role Role) {
   session.SetValue(ROLE_KEY, role)
   *this = role
}

これについて正しく考えさせてくれて、サラスに感謝します。

2
Dale

あなたの場合、私はそれらにRoleCheckerRoleAssumerという名前を付けます。これは「マージされた」RoleCheckerAssumerです。または、単一のインターフェイスを使用する場合は、RoleHelperまたはRoleCheckerになります。

ServerSessionも問題ありません。またはSession(特に「クライアント」セッションがない場合)でも問題ありません。 ServerSessionerは悪いですが、Sessionは動詞でもインターフェースのメソッドでもありません。


規約に関する多くの投稿がありました。

有効なGo:インターフェイス名:

慣例により、1メソッドインターフェイスは、メソッド名に-erサフィックスまたはエージェント名詞を構築するための同様の変更を加えた名前が付けられます:ReaderWriterFormatterCloseNotifierなど.

そのような名前は多数あり、それらとそれらがキャプチャする関数名を尊重することは生産的です。 ReadWriteCloseFlushStringなどには、標準的な署名と意味があります。混乱を避けるために、同じシグネチャと意味を持たない限り、メソッドにこれらの名前の1つを与えないでください。逆に、型が既知の型のメソッドと同じ意味を持つメソッドを実装する場合、同じ名前と署名を付けます。 Stringではなく、ToStringというストリングコンバーターメソッドを呼び出します。

インターフェースの種類@名前には何がある?-golang.orgでのトーク

1つのメソッドのみを指定するインターフェイスは、通常、「er」が付加された関数名になります。

type Reader interface {
    Read(p []byte) (n int, err error)
}

結果が正しい英語でない場合もありますが、とにかくそれを行います。

type Execer interface {
    Exec(query string, args []Value) (Result, error)
}

時々英語を使って見やすくします:

type ByteReader interface {
    ReadByte() (c byte, err error)
}

インターフェイスに複数のメソッドが含まれる場合、その目的を正確に説明する名前を選択します(例:net.Conn、http.ResponseWriter、io.ReadWriter)。

レシーバー名には、thisselfなどを使用しないでください。代わりに:

名前@受信者@何ですか?-golang.orgでのトーク

受信者は特別な種類の議論です。

通常、ほとんどすべての行に表示されるため、これらはレシーバタイプを反映する1つまたは2つの文字です。

func (b *Buffer) Read(p []byte) (n int, err error)

func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)

func (r Rectangle) Size() Point

レシーバー名は、型のメソッド全体で一貫している必要があります。 (あるメソッドではrを使用し、別のメソッドではrdrを使用しないでください。)

コードレビューのコメントに移動:受信者名:

メソッドのレシーバーの名前は、そのアイデンティティを反映する必要があります。多くの場合、そのタイプの1文字または2文字の略語で十分です(「クライアント」の「c」または「cl」など)。 「me」、「this」、「self」などの汎用名は使用しないでください。これらは、関数ではなくメソッドに重点を置くオブジェクト指向言語の典型的な識別子です。名前は、メソッドの引数のように説明的なものである必要はありません。その役割は明らかであり、ドキュメンタリーの目的には役立たないからです。タイプのすべてのメソッドのほぼすべての行に表示されるため、非常に短い場合があります。親しみやすさは簡潔さを認めています。また、一貫性を保ちます。あるメソッドでレシーバー「c」を呼び出す場合、別のメソッドで「cl」を呼び出さないでください。

29
icza

Golangの慣例では、1メソッドのインターフェイス名はアクションの実行者を示す名詞です。例えば、

the `Read` method implements the `Reader` interface, and
the `Generate` method implements the `Generator` interface.

これが何であるかに関係なく、規約の詳細を明確にすることが最善です。これは、インターフェースが1つだけの機能または非常に特定の機能セットが必要な場合に役立ちます。

関数の最低公約数にIプレフィックスを使用する慣行があります。この場合、IRoleは、すべてのインターフェイスで満たされる必要のある2つの関数を定義するため、より良いインターフェイス名になります。 Roleを表す型