Eu estou familiarizado com as switch
instruções no Swift, mas me pergunto como substituir esse trecho de código por um switch
:
if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
swift
switch-statement
Pieter
fonte
fonte
Respostas:
Aqui está uma abordagem. Supondo que
someVar
seja umInt
ou outroComparable
, você pode opcionalmente atribuir o operando a uma nova variável. Isso permite que você faça o escopo da maneira que desejar, usando awhere
palavra-chave:Isso pode ser um pouco simplificado:
Você também pode evitar a
where
palavra - chave inteiramente com a correspondência de intervalos:fonte
default: fatalError()
detectar possíveis erros de lógica cedo.assertionFailure
parece ser uma opção mais segura, especialmente quando se trabalha em equipe.Com o Swift 5, você pode escolher uma das seguintes opções para substituir sua instrução if.
# 1 Usando a chave com
PartialRangeFrom
ePartialRangeUpTo
# 2 Usando a chave com
ClosedRange
eRange
# 3 Usando switch com a cláusula where
# 4 Usando switch com a cláusula where e a atribuição a
_
# 5 Usando o switch com
RangeExpression
o~=(_:_:)
operador do protocolo# 6 Usando o switch com
Equatable
o~=(_:_:)
operador do protocolo# 7 Utilizando switch com
PartialRangeFrom
,PartialRangeUpTo
eRangeExpression
'scontains(_:)
métodofonte
0.1
gera um erro fatal porque1...
cobre apenas números de 1. Portanto, esta solução funciona apenas sevalue
for um,Int
mas isso é perigoso porque se o tipo de variável for alterado, a funcionalidade será interrompida sem nenhum erro do compilador.A
switch
declaração, sob o capô, usa o~=
operador. Então, é isso:Desugars para isso:
Se você olhar para a referência da biblioteca padrão, ela poderá dizer exatamente o que a
~=
sobrecarga deve fazer : incluída é a correspondência de intervalo e a equivalência para coisas equitativas. (Não incluído é a correspondência enum-case, que é um recurso de idioma, e não uma função na lib std)Você verá que ele não corresponde a um booleano direto no lado esquerdo. Para esse tipo de comparação, você precisa adicionar uma declaração where.
A menos que você sobrecarregue o
~=
operador você mesmo. (Isso geralmente não é recomendado) Uma possibilidade seria algo como isto:Portanto, isso corresponde a uma função que retorna um booleano à esquerda para seu parâmetro à direita. Aqui está o tipo de coisa para a qual você poderia usá-lo:
Para o seu caso, você pode ter uma declaração parecida com esta:
Mas agora você precisa definir novas
isNegative
eisPositive
funções. A menos que você sobrecarregue mais alguns operadores ...Você pode sobrecarregar operadores de infixo normais para serem operadores de prefixo ou pós-fixado. Aqui está um exemplo:
Isso funcionaria assim:
Combine isso com a função anterior, e sua instrução switch pode ser assim:
Agora, você provavelmente não deveria usar esse tipo de coisa na prática: é um pouco desonesto. Você (provavelmente) está melhor aderindo à
where
declaração. Dito isto, o padrão de instrução switch deou
Parece bastante comum para que valha a pena considerar.
fonte
Você pode:
fonte
Como alguém já postou
case let x where x < 0:
aqui, é uma alternativa para ondesomeVar
está umInt
.E aqui está uma alternativa para onde
someVar
está umDouble
:fonte
É assim que se parece com os intervalos
fonte
A
<0
expressão não funciona (mais?), Então acabei com isso:Swift 3.0:
fonte
X_MAX
foi substituída por.greatestFiniteMagnitude
, ou sejaDouble.greatestFiniteMagnitude
,CGFloat.greatestFiniteMagnitude
etc. Por isso, normalmente, você pode apenas fazercase 0..< .greatestFiniteMagnitude
uma vez que o tipo desomeVar
já se sabevar timeLeft = 100
switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }
Por que o<=
operador não é reconhecido? Se eu escrever sem o igual, funciona. Graçascase 0...7200:
O operador<=
é um operador de comparação. Em um switch, você só pode usar operadores de intervalo (consulte a documentação)someVar
era umInt
e eu tinha que fazerDouble(
someVar) `para que ele funcione ...Que bom que o Swift 4 resolve o problema:
Como solução alternativa em 3, fiz:
Funciona, mas não é o ideal
fonte