2016-08-09 47 views
4

我只是张贴我的代码:接口命名约定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”。这是“惯用”吗?

有什么建议吗?

+1

我只是称之为'角色支持',但要达到英语水平。事实上,这将是一个有趣的尝试。请考虑不要使用'this'来命名方法接收器:这被认为是单向性的Go。讨论这些问题的[一个例子](http://stackoverflow.com/q/23482068/720999)。 – kostix

+0

是的,我一直在努力接收机名称。我知道这个成语是使用单个字母变量....我很抱歉,我不能那样做。 “这个”或“自我”在任何其他语言中都非常普遍,它可以消除歧义。 “角色支持”是可以的,但并不适合整洁的模式。 – Dale

+1

不是单个字母,而是有意义的缩写 - 单个字母可以用于短的功能(包括您的)。 “任何其他语言”肯定是一个严重的分解。那么,出于某种原因,这对我来说不是问题:不同的语言只是感觉不同。新手程序员的确努力成为一招狗,试图将他们的学习技能集成到他们面对的任何新语言中(一直在我自己身边),但理解语言背后的哲学并坚持下去总是更好。 – kostix

回答

1
的类型来satiisfied两种功能的做法

我明白了,tur我可以使用“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 
} 

谢谢Sarathsp让我正确地思考这件事。

1

在golang按照惯例,单方法接口名称是 名词,表示操作执行者。例如,

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

这将是最好的,使该公约的具体明确的,不管他们are.This善有善报好时,只有一个功能或一组特定的功能,通过该接口要求

有使用I前缀的功能最小公分母,在这种情况下IRole将是一个更好的界面名称作为接口定义了必须由所有代表Role

+0

IsRoler和AssumeRoler - > IsserAssumer?大声笑,这可能会更好的英文堆栈交换.... – Dale

+0

@戴尔https://talks.golang.org/2014/names.slide#14 =>有时结果是不正确的英语,但我们这样做无论如何: –

10

在你的情况下,我只是将它们命名为RoleChecker和,“合并”一个RoleCheckerAssumer。或者,如果您想要使用单个界面,那可能是RoleHelperRoleChecker

ServerSession也很好,甚至只是Session(特别是如果没有“客户”会话)。另一方面ServerSessioner是坏的,Session不是接口的动词而不是方法。


关于这些约定有很多帖子。

Effective Go: Interface names:

按照惯例,一个方法接口由该方法name加上后缀-er或类似的修改命名构建的试剂名:ReaderWriterFormatterCloseNotifier

有许多这样的名字,并且对它们以及它们捕获的函数名称进行高效的表示。 Read,Write,Close,Flush, String等都具有规范签名和含义。为了避免混淆,除非它具有相同的签名和含义,否则不要给你的方法一个这样的名字。相反,如果你的类型实现了一个与着名类型的方法具有相同含义的方法,给它一个相同的名字和签名;请致电您的字符串转换器方法String而不是ToString

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

接口指定只有一个方法通常只是附加到它的“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或类似的名称。相反:

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

接收器是一种特殊的说法。

按照惯例,他们反映的接收器类型, 一个或两个字符,因为它们通常出现在几乎每一个行:

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

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

func (r Rectangle) Size() Point 

接收器的名称应该是跨越式的方法一致。 (不要在另外一个方法和RDR使用河)

Go Code Review Comments: Receiver Names:

的方法的接收器的名称应该是其身份的反映;通常一个字母的一个或两个字母的缩写就足够了(例如“客户”的“c”或“cl”)。不要使用通用名称,比如“me”,“this”或“self”,这些名称是面向对象的语言的典型代码,与函数相比,它更强调方法。这个名字不必像方法论证那样具有描述性,因为它的作用是显而易见的,并且没有任何文献目的。它可能很短,因为它几乎出现在每种类型的每种方法的每一行上;熟悉承认简洁。也要保持一致:如果您用一种方法调用接收器“c”,则不要在另一个方法中将其称为“cl”。

+0

单一方法接口“更容易”。 “是()”扔了我。我最终只使用“checker()”。是的,抱歉,不会使用单个或两个字母标识符。我不在乎这里的习惯用法。我知道使用这种或者自己的六种语言,为什么我会在这里打破约定,仅仅是因为语言规范中的一些文档说我应该?这或我自己正是我的意思和我想要的。在一天结束时,我需要阅读我的代码,并且如果我翻阅我的speghetti单个字母标识符,那有什么意义? – Dale

+3

@Dale你可以做任何你想做的事。没有人会强迫你做任何事情。只要你编码“独自”,它不会打扰其他人。但是,如果你想与他人合作,或者其他人需要使用你的代码,你需要说一个“通用”的语言。关于'this'和'self'作为接收方的方法:[在Go中将接收方变量命名为'self'误导性或良好实践?](http://stackoverflow.com/questions/23482068/in-go-is-naming - 接收者 - 变量 - 自我误导或良好实践) – icza

+0

谢谢。我不想争论。我打算开放这个堆。也许反馈会迫使我重新思考我的决定。我仍然不相信这里的设计师的决定。这就是说,我在Go上看到的所有其他东西都非常令人印象深刻。 – Dale