我发布我的代码:
/*
* 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 ++惯例只是抛出一个"我"在一切之前。这是"惯用"?
有什么建议吗?
答案 0 :(得分:27)
在您的情况下,我只会将它们命名为RoleChecker
和RoleAssumer
,"合并"一个RoleCheckerAssumer
。或者,如果您使用单一界面,可以是RoleHelper
或RoleChecker
。
ServerSession
也很好,甚至只是Session
(特别是如果没有"客户端"会话)。另一方面,ServerSessioner
不好,Session
不是动词,也不是界面的方法。
有很多关于这些公约的帖子。
Effective Go: Interface names:
按照惯例,单方法接口由方法名称加上-er后缀或类似修改来命名,以构造代理名词:
Reader
,Writer
,Formatter
,{{ 1}}等等。有许多这样的名字,它们很有效地兑现了它们以及它们捕获的功能名称。
CloseNotifier
,Read
,Write
,Close
,Flush
等具有规范的签名和含义。为避免混淆,除非具有相同的签名和含义,否则请不要将您的方法作为其中一个名称。相反,如果您的类型实现的方法与众所周知类型的方法具有相同的含义,请为其指定相同的名称和签名;将您的字符串转换器方法String
称为String
。
Interface Types @ What's in a name? - Talks at golang.org
仅指定一种方法的接口通常只是具有' er'的函数名称。附加到它。
ToString
有时候结果并不是正确的英语,但无论如何我们都会这样做:
type Reader interface { Read(p []byte) (n int, err error) }
有时我们会使用英语让它变得更好:
type Execer interface { Exec(query string, args []Value) (Result, error) }
当接口包含多个方法时,请选择准确描述其用途的名称(例如:net.Conn,http.ResponseWriter,io.ReadWriter)。
对于收件人姓名,请勿使用type ByteReader interface {
ReadByte() (c byte, err error)
}
或this
或类似的名称。代替:
Receivers @ What's in a name? - Talks at golang.org
接收者是一种特殊的论点。
按照惯例,它们是反映接收器类型的一个或两个字符, 因为它们通常几乎出现在每一行上:
self
接收者名称在类型的方法中应该是一致的。 (不要在一种方法中使用r而在另一种方法中使用rdr。)
Go Code Review Comments: Receiver Names:
方法接收者的名字应该反映其身份;通常,其类型的一个或两个字母缩写就足够了(例如" c"或" cl"对于"客户")。不要使用通用名称,例如" me","这个"或者" self",面向对象语言的典型标识符,更强调方法而不是函数。名称不必像方法论证那样具有描述性,因为它的作用是显而易见的,不起任何文件目的。它可以很短,因为它几乎出现在每种类型的每个方法的每一行上;熟悉承认简洁。也要保持一致:如果你打电话给接收器" c"在一种方法中,不要称之为" cl"在另一个。
答案 1 :(得分:2)
我知道了,事实证明我可以使用“呃”惯例。
/*
* 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让我正确地思考这个问题。
答案 2 :(得分:1)
在golang中按照惯例,单方法接口名称是 名词表示行动的实施者。例如,
the `Read` method implements the `Reader` interface, and
the `Generate` method implements the `Generator` interface.
最好使公约的细节清晰,无论它们是什么。当接口只需要一个功能或一组非常特定的功能时,这很好。
有一种做法是将I
前缀用于函数的最低公分母,在这种情况下IRole
将是一个更好的接口名称,因为接口定义了两个必须满足所有人的功能表示Role