coffeescript和enum值

时间:2012-02-20 23:05:55

标签: enums coffeescript

我在coffeescript(http://coffeescript.org/)中使用了枚举/常量的概念,并在下面提出了以下代码,似乎没问题。对于枚举适合的东西,我怎样才能提高它?谷歌搜索这个还没有表现出满意。

class SomeService

  @SomeEnumValue : 400
  @SomeOtherValue : 402

  someFunc: ->
    SomeService.SomeEnumValue 

ok = new SomeService()
alert ok.someFunc()

if (ok.someFunc() == SomeService.SomeEnumValue) then alert ' some enum value'

6 个答案:

答案 0 :(得分:19)

enum的整个概念在动态语言中是无用的,如元组,类型列表,地图和许多其他东西,Javascript(Coffeescript)是动态的。使用动态语言时,您只需忘记类型检查并使用现有的更通用的结构来解决您的问题。使用数组而不是列表和元组,使用对象而不是映射和枚举,只需信任传递给函数的值类型,但对代码进行大量单元测试。无论好坏(对于更糟糕的IMO),这就是在这里完成工作的方式。

在您的情况下,我建议您将值存储在单个对象中,如下所示:

HTTPStatusCodes = 
  ok : 200
  badRequest : 400
  unauthorized : 401

并像这样访问它:

class SomeService
  okCode: ->
    HTTPStatusCodes.ok
  failureCodes: ->
    code for key, code of HTTPStatusCodes when code >= 400

答案 1 :(得分:5)

我知道我迟到了,但是为了后人,我提出了一个“coffeethonic”解决方案(本着打字少的精神):

[ a, b, c ] = [1..3]

答案 2 :(得分:4)

我强烈不同意由于Javascript的动态特性或Enums不太美化的哈希值而使Enums无用的说法。

引用维基百科:“已声明具有枚举类型的变量可以作为值分配给任何枚举器。” 只有这些枚举器可以作为值。

Coffeescript可以轻松地在语法上取悦模仿Enum。包括对无效枚举值的错误处理(尽管仅在运行时)

我创建了一个主要是功能性的示例并使用匿名回调 作为赋值的函数 - 基本上用赋值运算符“=”代替 Coffeescripts功能操作符“ - >”。它是我书中语法密集度最高的代码。 然而,更多基于类的方法当然是可能的。

#define enumeration
httpcodes = Enum 
    ok: 200
    badRequest: 400
    unauthorized: 401
    server_error: 500

#set enum variables with some default state
chrome = httpcodes -> @server_error 
firefox = httpcodes -> @server_error
safari = httpcodes -> @server_error

console.log "httpcodes.ok:" + httpcodes.ok

#change enum value
chrome -> @ok
firefox -> @badRequest
safari -> @unauthorized

console.log "chrome:" + chrome ->
console.log "firefox:" + firefox ->
console.log "safari:" + safari ->

console.log "(chrome ->) == httpcodes.ok:" + ((chrome ->) == httpcodes.ok)

#set an invalid value
try
    safari -> 999
catch err
    console.log err 
    console.log "safari:" + safari ->

这是创建枚举的代码(您需要将其置于代码之上) 如果你想运行它。只是想在实现代码之前显示使用代码

Enum = (enumeration)->
    check = (value)->
        newval = null
        for key, val of enumeration
            if val == value
                newval = value
                break
        if !newval
            throw "Invalid Enum Value: #{value}"

     result = (init)->
         state = init.call(enumeration)
         check state
         (callback)->
              value = callback.call(enumeration)
              if value == null or value == undefined
                  return state
              else
                  check value
                  state = value

      for key, value of enumeration
          result[key] = value 

      result

显然,如果Coffeescript有语法宏会更好。 所以我们可以写

Enum httpcodes
    ok: 200
    badrequest: 400

chrome = httpcodes 'ok
#or
chrome := 'ok

答案 3 :(得分:2)

Colors = Object.freeze({
  RED: 'red'
  GREEN: 'green'
  BLUE: 'blue'
})
console.log Colors.RED
# red

值是常量(您无法更改它们):

Colors.RED = 'black'
console.log Colors.RED
# red

答案 4 :(得分:1)

我开始对coffeescript中的enums感到疑惑,并以解决方案I published on github (available in npm, bower, meteor too)结束。我尝试开发类似java的枚举,但考虑到原型继承和经典继承coffeescript之间的混合,我更加灵活。

以下是适合您代码的方式:

class SomeService
  someFunc: -> SomeService.SomeEnumValue
  #A cool hack, but it must be the last class statement. 
  #Your class will now inherit this enumeration's properties. 
  #If you find this too hacky, you can always have a public static 
  #states class property instead.
  @__proto__:new Enumeration('SomeService',{
          SomeEnumValue :400
          SomeOtherValue:402
      })

ok = new SomeService()

alert ok.someFunc().id() #shows 400

if (ok.someFunc() is SomeService.SomeEnumValue) then alert ' some enum value'

但是在这个实现中很酷的是,你的枚举可以有特定的字段,并且继承自原型(3d构造函数参数),但保证了唯一性。这允许您重构代码并在这些函数中移动一些逻辑。现在让我们通过定义tell函数来询问此枚举值,以便在需要时告诉我们。

class SomeService
  someFunc: -> SomeService.SomeEnumValue
  #A cool hack, but it must be the last class statement. 
  #Your class will now inherit this enumeration's properties. 
  #If you find this too hacky, you can always have a public static 
  #states class property instead.
  @__proto__:new Enumeration('SomeService',
                SomeEnumValue : { _id:400, text: ' some enum value' }
                SomeOtherValue: { _id:402, text: null } 
        , tell:->if @text? then alert @text)

ok = new SomeService()

alert ok.someFunc().id() #shows 400

ok.someFunc().tell()

希望这有助于某人,您可以查看github地址,看看我写的实现和一些更详细的文档。

答案 5 :(得分:1)

对于正在寻找更简单解决方案的人们来说,键的值无关紧要,它不必是故障安全的:

Priority = {
  "LOW"
  "HIGH"
}

priority = Priority.HIGH