dongshou9343
2016-08-09 05:05 阅读 149
已采纳

接口命名约定Golang

I'll just post my code:

/*
*  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
}

It should be noted that ServerSession is also an interface, calling "ServerSessioner" just feels wonky to me.

I'm toying with the idea of creating an interface with IsRole() and AssumeRole(), however "Roler" seems very wonky. It's dawning on me that I don't really know or have ever come across naming conventions for interfaces, other than the standard "er" suffix. I do seem to recall the VS C++ convention is to just throw an "I" in front of everything. Is this "idiomatic"?

Any suggestions?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

3条回答 默认 最新

  • 已采纳
    dongzhong8834 dongzhong8834 2016-08-09 06:14

    I got it, turns out I can use the "er" convention.

    /*
    *  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
    }
    

    Thank you Sarathsp for getting me thinking about this properly.

    点赞 评论 复制链接分享
  • dtu15253 dtu15253 2016-08-09 05:56

    In golang By convention, one-method interface names are nouns denoting the doer of an action. For example,

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

    It would be best to make the specifics of the convention clear,regardless of what they are.This goes good when there is only one function or a very specific set of functions are required by the interface

    There is a practise of using I prefix to Lowest Common Denominator of the functions ,in this case IRole would be a better interface name as the interface defines two functions that has to be satiisfied by all the types representing Role

    点赞 评论 复制链接分享
  • dongyou8368 dongyou8368 2016-08-09 08:06

    In your case I would just name them RoleChecker and RoleAssumer, the "merged" one RoleCheckerAssumer. Or if you'd go with a single interface, that could be RoleHelper or RoleChecker.

    ServerSession is also fine, or even just Session (especially if there is no "client" session). ServerSessioner on the other hand is bad, Session is not a verb and not a method of the interface.


    There has been many posts about the conventions.

    Effective Go: Interface names:

    By convention, one-method interfaces are named by the method name plus an -er suffix or similar modification to construct an agent noun: Reader, Writer, Formatter, CloseNotifier etc.

    There are a number of such names and it's productive to honor them and the function names they capture. Read, Write, Close, Flush, String and so on have canonical signatures and meanings. To avoid confusion, don't give your method one of those names unless it has the same signature and meaning. Conversely, if your type implements a method with the same meaning as a method on a well-known type, give it the same name and signature; call your string-converter method String not ToString.

    Interface Types @ What's in a name? - Talks at golang.org

    Interfaces that specify just one method are usually just that function name with 'er' appended to it.

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

    Sometimes the result isn't correct English, but we do it anyway:

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

    Sometimes we use English to make it nicer:

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

    When an interface includes multiple methods, choose a name that accurately describes its purpose (examples: net.Conn, http.ResponseWriter, io.ReadWriter).

    For receiver names, don't use this or self or similar ones. Instead:

    Receivers @ What's in a name? - Talks at golang.org

    Receivers are a special kind of argument.

    By convention, they are one or two characters that reflect the receiver type, because they typically appear on almost every line:

    func (b *Buffer) Read(p []byte) (n int, err error)
    
    func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request)
    
    func (r Rectangle) Size() Point
    

    Receiver names should be consistent across a type's methods. (Don't use r in one method and rdr in another.)

    Go Code Review Comments: Receiver Names:

    The name of a method's receiver should be a reflection of its identity; often a one or two letter abbreviation of its type suffices (such as "c" or "cl" for "Client"). Don't use generic names such as "me", "this" or "self", identifiers typical of object-oriented languages that place more emphasis on methods as opposed to functions. The name need not be as descriptive as that of a method argument, as its role is obvious and serves no documentary purpose. It can be very short as it will appear on almost every line of every method of the type; familiarity admits brevity. Be consistent, too: if you call the receiver "c" in one method, don't call it "cl" in another.

    点赞 评论 复制链接分享

相关推荐