Как реализовать Перечисления в Ruby?

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

312
задан Trilarion 31 May 2019 в 02:22
поделиться

8 ответов

Два пути. Символы (:foo нотация) или константы (FOO нотация).

Символы являются соответствующими, когда Вы хотите улучшить удобочитаемость, не замусорив код литеральными строками.

postal_code[:minnesota] = "MN"
postal_code[:new_york] = "NY"

Константы являются соответствующими, когда у Вас есть базовое значение, которое важно. Просто объявите, что модуль содержит Ваши константы и затем объявляет константы в этом.

module Foo
  BAR = 1
  BAZ = 2
  BIZ = 4
end

flags = Foo::BAR | Foo::BAZ # flags = 3
305
ответ дан Andrew Marshall 23 November 2019 в 01:10
поделиться

Большинство людей использует символы (это :foo_bar синтаксис). Они - вид уникальных непрозрачных значений. Символы не принадлежат никакому перечислимому типу стиля, таким образом, они не действительно точное представление типа перечисления C, но это в значительной степени столь хорошо, как это добирается.

1
ответ дан Jan Krüger 23 November 2019 в 01:10
поделиться

Символы являются рубиновым путем. Однако иногда одна потребность говорить с некоторым кодом C или чем-то или Java, которые представляют некоторое перечисление для различных вещей.

<час>
#server_roles.rb
module EnumLike

  def EnumLike.server_role
    server_Symb=[ :SERVER_CLOUD, :SERVER_DESKTOP, :SERVER_WORKSTATION]
    server_Enum=Hash.new
    i=0
    server_Symb.each{ |e| server_Enum[e]=i; i +=1}
    return server_Symb,server_Enum
  end

end
<час>

Это может тогда использоваться как этот

<час>
require 'server_roles'

sSymb, sEnum =EnumLike.server_role()

foreignvec[sEnum[:SERVER_WORKSTATION]]=8
<час>

, Это, может, конечно, быть сделан абстрактным, и можно прокрутить наш собственный Класс Enum

2
ответ дан Jonke 23 November 2019 в 01:10
поделиться

Все это зависит, как Вы используете Java или перечисления C#. То, как Вы используете его, продиктует решение, которое Вы выберете в Ruby.

Попытка собственный компонент Set тип, например:

>> enum = Set['a', 'b', 'c']
=> #<Set: {"a", "b", "c"}>
>> enum.member? "b"
=> true
>> enum.member? "d"
=> false
>> enum.add? "b"
=> nil
>> enum.add? "d"
=> #<Set: {"a", "b", "c", "d"}>
3
ответ дан mislav 23 November 2019 в 01:10
поделиться

Кто-то шел вперед и записал рубиновый драгоценный камень, названный Renum. Это утверждает, что получило самый близкий Java/C# как поведение. Лично я все еще изучаю Ruby, и я был немного потрясен, когда я хотел заставить определенный класс содержать статическое перечисление, возможно хеш, которым это не было точно легко найдено через Google.

4
ответ дан dlamblin 23 November 2019 в 01:10
поделиться

Самый идиоматический способ сделать это должно использовать символы. Например, вместо:

enum {
  FOO,
  BAR,
  BAZ
}

myFunc(FOO);

... можно просто использовать символы:

# You don't actually need to declare these, of course--this is
# just to show you what symbols look like.
:foo
:bar
:baz

my_func(:foo)

Это более открыто, чем перечисления, но это соответствует хорошо духу Ruby.

Символы также работают очень хорошо. Сравнение двух символов для равенства, например, намного быстрее, чем сравнение двух строк.

52
ответ дан emk 23 November 2019 в 01:10
поделиться

Другой подход - использовать класс Ruby с хешем, содержащим имена и значения, как описано в следующем сообщении блога RubyFleebie . Это позволяет легко преобразовывать значения между значениями и константами (особенно если вы добавляете метод класса для поиска имени данного значения).

0
ответ дан 23 November 2019 в 01:10
поделиться

Я думаю, что лучший способ реализовать перечисление как типы - это использовать символы, поскольку они в значительной степени ведут себя как целые числа (когда они приходит на перформанс, object_id используется для сравнения); вам не нужно беспокоиться об индексировании, и они выглядят очень аккуратно в вашем коде xD

0
ответ дан 23 November 2019 в 01:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: