Меньше или больше, чем в операторе Swift switch



Я знаком с switch операторы в Swift, но интересно, как заменить этот кусок кода на switch:



if someVar < 0 {
// do something
} else if someVar == 0 {
// do something else
} else if someVar > 0 {
// etc
}
624   8  

8 ответов:

вот один подход. Предполагая, что someVar - это Int и Comparable, вы можете дополнительно назначить операнд новой переменной. Это позволяет вам охватить его, однако вы хотите использовать where ключевые слова:

var someVar = 3

switch someVar {
case let x where x < 0:
    print("x is \(x)")
case let x where x == 0:
    print("x is \(x)")
case let x where x > 0:
    print("x is \(x)")
default:
    print("this is impossible")
}

это можно немного упростить:

switch someVar {
case _ where someVar < 0:
    print("someVar is \(someVar)")
case 0:
    print("someVar is 0")
case _ where someVar > 0:
    print("someVar is \(someVar)")
default:
    print("this is impossible")
}

вы также можете избежать where ключевое слово полностью с диапазоном соответствия:

switch someVar {
case Int.min..<0:
    print("someVar is \(someVar)")
case 0:
    print("someVar is 0")
default:
    print("someVar is \(someVar)")
}

С помощью Swift 4 Вы можете выбрать один из следующих коммутаторов для замены вашего оператора if.


#1 с помощью переключателя с CountablePartialRangeFrom и PartialRangeUpTo

let value = 1

switch value {
case 1...:
    print("greater than zero")
case 0:
    print("zero")
case ..<0:
    print("less than zero")
default:
    fatalError()
}

#2 с помощью переключателя с CountableClosedRange,CountableRange,Int ' s max статическое свойство и Int ' s min статическое свойство

let value = 1

switch value {
case 1 ... Int.max:
    print("greater than zero")
case Int.min ..< 0:
    print("less than zero")
case 0:
    print("zero")
default:
    fatalError()
}

#3 с помощью переключателя с предложением where

let value = 1

switch value {
case let val where val > 0:
    print("\(val) is greater than zero")
case let val where val == 0:
    print("\(val) is zero")
case let val where val < 0:
    print("\(val) is less than zero")
default:
    fatalError()
}

#4 с помощью переключателя с предложением where и назначение на _

let value = 1

switch value {
case _ where value > 0:
    print("greater than zero")
case _ where value == 0:
    print("zero")
case _ where value < 0:
    print("less than zero")
default:
    fatalError()
}

#5 с помощью переключателя с RangeExpression протокол ~=(_:_:) оператор

let value = 1

switch true {
case 1... ~= value:
    print("greater than zero")
case ..<0 ~= value:
    print("less than zero")
default:
    print("zero")
}

#6 с помощью выключателя с Equatable протокол ~=(_:_:) оператор

let value = 1

switch true {
case value > 0:
    print("greater than zero")
case value < 0:
    print("less than zero")
case 0 ~= value:
    print("zero")
default:
    fatalError()
}

#7 с помощью переключателя с CountablePartialRangeFrom,PartialRangeUpTo и RangeExpression ' s contains(_:) метод

let value = 1

switch true {
case (1...).contains(value):
    print("greater than zero")
case (..<0).contains(value):
    print("less than zero")
default:
    print("zero")
}

The switch заявление, под капотом, использует ~= оператора. Так вот:

let x = 2

switch x {
case 1: print(1)
case 2: print(2)
case 3..<5: print(3..<5)
default: break
}

Desugars к этому:

if 1          ~= x { print(1) }
else if 2     ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else {  }

если вы посмотрите на стандартные библиотеки, он может сказать вам точно, что ~= перегружен, чтобы сделать: в комплекте идет согласование диапазона и приравнивание к равным вещам. (Не входит в комплект, является enum-случае соответствия, что является особенностью языка, а не функция стандартной библиотеки)

вы увидите, что он не соответствует прямому булеву с левой стороны. Для такого рода сравнений необходимо добавить оператор where.

если только... вы перегружаете ~= оператором. (Это вообще не рекомендуется) одна возможность будет что-то вроде этого:

func ~= <T> (lhs: T -> Bool, rhs: T) -> Bool {
  return lhs(rhs)
}

так что соответствует функция, которая возвращает логическое значение слева значение справа. Вот такая вещь, которую вы могли бы использовать ибо:

func isEven(n: Int) -> Bool { return n % 2 == 0 }

switch 2 {
case isEven: print("Even!")
default:     print("Odd!")
}

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

switch someVar {
case isNegative: ...
case 0: ...
case isPositive: ...
}

но теперь вы должны определить новый isNegative и isPositive функции. Если вы не перегрузите еще несколько операторов...

вы можете перегружать обычные инфиксные операторы, чтобы быть карри префиксными или постфиксными операторами. Вот пример:

postfix operator < {}

postfix func < <T : Comparable>(lhs: T)(_ rhs: T) -> Bool {
  return lhs < rhs
}

это будет работать примерно так:

let isGreaterThanFive = 5<

isGreaterThanFive(6) // true
isGreaterThanFive(5) // false

объедините это с более ранней функцией и вашим коммутатором заявление может выглядеть так:

switch someVar {
case 0< : print("Bigger than 0")
case 0  : print("0")
default : print("Less than 0")
}

теперь, вы, вероятно, не должны использовать такие вещи на практике: это немного изворотливо. Вы (вероятно) лучше придерживаться where заявление. Тем не менее, шаблон оператора switch

switch x {
case negative:
case 0:
case positive:
}

или

switch x {
case lessThan(someNumber):
case someNumber:
case greaterThan(someNumber):
}

кажется достаточно распространенным, чтобы это стоило рассмотреть.

вы можете:

switch true {
case someVar < 0:
    print("less than zero")
case someVar == 0:
    print("eq 0")
default:
    print("otherwise")
}

так как кто-то уже написал case let x where x < 0: вот альтернатива для where someVar - это Int.

switch someVar{
case Int.min...0: // do something
case 0: // do something
default: // do something
}

и вот альтернатива для where someVar - это Double:

case -(Double.infinity)...0: // do something
// etc

вот как это выглядит с диапазонами

switch average {
    case 0..<40: //greater or equal than 0 and less than 40
        return "T"
    case 40..<55: //greater or equal than 40 and less than 55
        return "D"
    case 55..<70: //greater or equal than 55 and less than 70
        return "P"
    case 70..<80: //greater or equal than 70 and less than 80
        return "A"
    case 80..<90: //greater or equal than 80 and less than 90
        return "E"
    case 90...100: //greater or equal than 90 and less or equal than 100
        return "O"
    default:
        return "Z"
    }

The <0 выражение не работает (больше?) так что я закончил с этим:

Swift 3.0:

switch someVar {
    case 0:
        // it's zero
    case 0 ..< .greatestFiniteMagnitude:
        // it's greater than zero
    default:
        // it's less than zero
    }

рад, что Swift 4 решает эту проблему: В качестве обходного пути в 3 я сделал:

switch translation.x  {
    case  0..<200:
        print(translation.x, slideLimit)
    case  -200..<0:
        print(translation.x, slideLimit)
    default:
        break
    }

работает, но не идеально

Comments

    Ничего не найдено.