Acho que não entendo fundamentalmente o que enum
é e quando usá-lo.
Por exemplo:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
O que realmente está sendo declarado aqui?
Acho que não entendo fundamentalmente o que enum
é e quando usá-lo.
Por exemplo:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
O que realmente está sendo declarado aqui?
Respostas:
Três coisas estão sendo declarada aqui: um tipo enumerado anônimo é declarada, ShapeType
está sendo declarado um typedef para essa enumeração anônima, e os três nomes kCircle
, kRectangle
e kOblateSpheroid
estão sendo declarados como constantes integral.
Vamos quebrar isso. No caso mais simples, uma enumeração pode ser declarada como
enum tagname { ... };
Isso declara uma enumeração com a tag tagname
. Em C e Objective-C (mas não em C ++), qualquer referência a isso deve ser precedida com a enum
palavra - chave. Por exemplo:
enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
Para evitar ter que usar a enum
palavra - chave em qualquer lugar, um typedef pode ser criado:
enum tagname { ... };
typedef enum tagname tagname; // declare 'tagname' as a typedef for 'enum tagname'
Isso pode ser simplificado em uma linha:
typedef enum tagname { ... } tagname; // declare both 'enum tagname' and 'tagname'
E, finalmente, se não precisarmos usar enum tagname
a enum
palavra - chave, podemos tornar o enum
anônimo e apenas declará-lo com o nome typedef:
typedef enum { ... } tagname;
Agora, neste caso, estamos declarando ShapeType
ser um nome digitado com digitação de uma enumeração anônima. ShapeType
é realmente apenas um tipo integral, e só deve ser usado para declarar variáveis que possuem um dos valores listados na declaração (isto é, um dos kCircle
, kRectangle
e kOblateSpheroid
). ShapeType
Porém, você pode atribuir outro valor a uma variável lançando, portanto, tenha cuidado ao ler valores de enumeração.
Finalmente, kCircle
, kRectangle
, e kOblateSpheroid
são declarados como constantes integral no espaço de nomes global. Como nenhum valor específico foi especificado, eles são atribuídos a números inteiros consecutivos começando com 0, então kCircle
é 0, kRectangle
é 1 e kOblateSpheroid
é 2.
A Apple recomenda definir enums como este desde o Xcode 4.4 :
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Eles também fornecem uma macro útil NS_ENUM
:
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
Essas definições fornecem verificação de tipo mais forte e melhor conclusão de código. Não consegui encontrar a documentação oficial NS_ENUM
, mas você pode assistir ao vídeo "Objetivo Moderno-C" da sessão da WWDC 2012 aqui .
ATUALIZAÇÃO
Link para a documentação oficial aqui .
NS_ENUM
macro por NSHipster: NSHipster.com/ns_enum-ns_options
Um tipo definido de utilizador que tem os valores possíveis de kCircle
, kRectangle
, ou kOblateSpheroid
. Os valores dentro da enumeração (kCircle, etc) são visíveis fora da enumeração. É importante ter isso em mente ( int i = kCircle;
é válido, por exemplo).
Atualização para alterações de 64 bits: de acordo com os documentos da apple sobre alterações de 64 bits,
As enumerações também são digitadas: No compilador LLVM, os tipos enumerados podem definir o tamanho da enumeração. Isso significa que alguns tipos enumerados também podem ter um tamanho maior do que o esperado. A solução, como em todos os outros casos, é não fazer suposições sobre o tamanho de um tipo de dados. Em vez disso, atribua quaisquer valores enumerados a uma variável com o tipo de dados apropriado
Portanto, você deve criar um enum com o tipo abaixo da sintaxe, se for compatível com 64 bits.
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
ou
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Caso contrário, levará ao aviso como Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType
Atualização para programação rápida:
No Swift, há uma alteração de sintaxe.
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
A enum (abreviação de enumeração) é usada para enumerar um conjunto de valores (enumeradores). Um valor é uma coisa abstrata representada por um símbolo (uma palavra). Por exemplo, um enum básico pode ser
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };
Esse enum é chamado anônimo porque você não tem um símbolo para nomeá-lo. Mas ainda está perfeitamente correto. Basta usá-lo assim
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
Está bem. A vida é linda e tudo vai bem. Mas um dia você precisa reutilizar essa enum para definir uma nova variável para armazenar myGrandFatherPantSize, e então escreve:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;
Mas você tem um erro do compilador "redefinição de enumerador". Na verdade, o problema é que o compilador não tem certeza de que você primeiro enum e segundo descreve a mesma coisa.
Então, se você deseja reutilizar o mesmo conjunto de enumeradores (aqui xs ... xxxxl) em vários lugares, você deve marcá-lo com um nome exclusivo. Na segunda vez que você usa esse conjunto, basta usar a tag. Mas não esqueça que essa tag não substitui a palavra enum, mas apenas o conjunto de enumeradores. Depois, tome cuidado para usar enum como de costume. Como isso:
// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;
você também pode usá-lo em uma definição de parâmetro:
// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;
Você poderia dizer que reescrever enum em todos os lugares não é conveniente e faz com que o código pareça um pouco estranho. Você está certo. Um tipo real seria melhor.
Este é o passo final de nossa grande progressão para a cúpula. Apenas adicionando um typedef, vamos transformar nossa enumeração em um tipo real. Ah, a última coisa, typedef não é permitido em sua classe. Em seguida, defina seu tipo logo acima. Faça isso deste modo:
// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type
@interface myClass {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
Lembre-se de que a tag é opcional. Então, como aqui, nesse caso, não marcamos os enumeradores, mas apenas para definir um novo tipo. Então não precisamos mais disso.
// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;
@interface myClass : NSObject {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
@end
Se você estiver desenvolvendo no Objective-C com o XCode, deixarei descobrir algumas macros legais com o prefixo NS_ENUM. Isso deve ajudá-lo a definir boas enums facilmente e, além disso, ajudará o analisador estático a fazer algumas verificações interessantes antes de compilar.
Bom Enum!
typedef
é útil para redefinir o nome de um tipo de variável existente. Ele fornece uma maneira curta e significativa de chamar um tipo de dados. por exemplo:
typedef unsigned long int TWOWORDS;
aqui, o tipo não assinado long int é redefinido para ser do tipo TWOWORDS. Portanto, agora podemos declarar variáveis do tipo unsigned long int escrevendo,
TWOWORDS var1, var2;
ao invés de
unsigned long int var1, var2;
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
então você pode usá-lo como: -
ShapeType shape;
e
enum {
kCircle,
kRectangle,
kOblateSpheroid
}
ShapeType;
agora você pode usá-lo como: -
enum ShapeType shape;
enum é usado para atribuir valor a enum elementos que não podem ser feitos em struct. Portanto, toda vez, em vez de acessar a variável completa, podemos fazê-lo pelo valor que atribuímos às variáveis em enum. Por padrão, ele começa com a atribuição 0, mas podemos atribuir a ele qualquer valor e a próxima variável em enum será atribuída com o valor anterior +1.
Você pode usar no formato abaixo, o valor padrão bruto a partir de 0, portanto
Você pode atribuir seu próprio valor inicial específico.
typedef enum : NSUInteger {
kCircle, // for your value; kCircle = 5, ...
kRectangle,
kOblateSpheroid
} ShapeType;
ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
Um typedef permite que o programador defina um tipo de Objective-C como outro. Por exemplo,
typedef int Contador; define o tipo Contador como equivalente ao tipo int. Isso melhora drasticamente a legibilidade do código.
O Typedef é uma palavra-chave em C e C ++. É usado para criar novos nomes para tipos de dados básicos (char, int, float, double, struct & enum) .
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Aqui ele cria o tipo de dados enumerado ShapeType e podemos escrever novos nomes para o tipo de enum ShapeType, conforme indicado abaixo
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
enum pode reduzir muitos tipos de "erros" e tornar o código mais gerenciável
#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER
A definição não possui restrições. É simplesmente apenas uma substituição. Não é capaz de limitar todas as condições do estado. Quando o estado é atribuído a 5, o programa estará errado, porque não há estado correspondente. Mas o compilador não avisa STATE = 5
Então é melhor usar assim
typedef enum SampleState {
SampleStateGood = 0,
SampleStateBad,
SampleStateOther
} SampleState;
SampleState state = SampleStateGood;