Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Два пути. Символы (: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
Большинство людей использует символы (это :foo_bar
синтаксис). Они - вид уникальных непрозрачных значений. Символы не принадлежат никакому перечислимому типу стиля, таким образом, они не действительно точное представление типа перечисления C, но это в значительной степени столь хорошо, как это добирается.
Символы являются рубиновым путем. Однако иногда одна потребность говорить с некоторым кодом 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
Все это зависит, как Вы используете 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"}>
Кто-то шел вперед и записал рубиновый драгоценный камень, названный Renum. Это утверждает, что получило самый близкий Java/C# как поведение. Лично я все еще изучаю Ruby, и я был немного потрясен, когда я хотел заставить определенный класс содержать статическое перечисление, возможно хеш, которым это не было точно легко найдено через Google.
Самый идиоматический способ сделать это должно использовать символы. Например, вместо:
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.
Символы также работают очень хорошо. Сравнение двух символов для равенства, например, намного быстрее, чем сравнение двух строк.
Другой подход - использовать класс Ruby с хешем, содержащим имена и значения, как описано в следующем сообщении блога RubyFleebie . Это позволяет легко преобразовывать значения между значениями и константами (особенно если вы добавляете метод класса для поиска имени данного значения).
Я думаю, что лучший способ реализовать перечисление как типы - это использовать символы, поскольку они в значительной степени ведут себя как целые числа (когда они приходит на перформанс, object_id используется для сравнения); вам не нужно беспокоиться об индексировании, и они выглядят очень аккуратно в вашем коде xD