Мы рады поделиться еще одним релизом Swiftify, который сделает вашу жизнь немного проще. На этот раз мы рассмотрим различия между тем, как Objective-C и Swift обрабатывают типы.
Введите приведение для объявлений цикла
Objective-C накладывает очень мало ограничений на приведение типов. При попытке выполнить операции над объектами в NSArray вы можете сделать что-то вроде этого:
- (void)loopOverStrings:(nonnull NSArray *)stringArray {
for (NSString *string in stringArray) {
[self doWorkOnString:string];
}
}
- (void)doWorkOnString:(NSString *)string {
// ...
}
В этом коде нигде не говорится, что stringArray на самом деле является массивом строк. Но Objective-C по-прежнему позволит вам преобразовывать объекты в stringArray в NSString.
Swift не допускает такого рода неявное преобразование. Попытка привести объекты в stringArray к типу String вернет необязательное значение, если это не удастся. Наш последний релиз обрабатывает приведение типов следующим образом:
func loopOverStrings(_ stringArray: [Any]) {
for string: String in stringArray as? [String] ?? [String]() {
doWork(on: string)
}
}
func doWork(on string: String?) {
}
Обратите внимание, что поскольку Objective-C stringArray не указывает тип своих объектов, версия Swift — [Any]. В объявлении цикла for мы приводим массив к [String].
Вы можете поиграть с этим примером здесь:
Неявное приведение к логическому значению
Что общего между 0, NO и nil в Objective-C?
Все они эквивалентны логическому значению false.
Это немного упрощение, но оно работает для следующей проблемы:
NSInteger var1 = -512;
NSInteger var2 = 512;
if (var1 + var2) {
NSLog(@"Sum is not zero");
}
Тело оператора if не будет выполнено, поскольку var1 + var2 == 0. 0 в Objective-C эквивалентен false, поэтому тело не выполняется. Если бы значение было отрицательным или положительным, оно равнялось бы true.
Мы исправляем эту причуду в последней версии:
var var1: Int = -512
var var2: Int = 512
if var1 + var2 != 0 {
print("Sum is not zero")
}
Это доступно для вас, чтобы попробовать на нашем сайте.
В том же духе мы можем проверить, является ли объект нулевым в Objective-C, следующим образом:
- (NSString *)resultMessageForData:(NSData *)data {
return data ? @"Operation succeeded!" : @"Operation failed.";
}
Если data не равно нулю, метод вернет «Операция выполнена успешно!». Если он равен нулю, вместо этого будет возвращено «Операция не удалась».
В преобразовании Swift нам нужно напрямую сравнить data с nil, потому что Swift не сделает этого за нас.
func resultMessage(for data: Data?) -> String? {
return data != nil ? "Operation succeeded!" : "Operation failed."
}
Попробуйте здесь:
Неявное преобразование нуля в логическое значение
Swiftify — конвертер Objective-C в Swiftswiftify.me
Необязательные параметры в интерполированных строках
Не знаю, как вы, но я столкнулся с изрядной долей ошибок, вызванных интерполяцией необязательных значений. В Swift вы можете легко комбинировать одну строку с другим объектом:
func logDate(date: Date?) {
print("The date is \(date)")
}
Вы можете ожидать такой вывод:
The date is 2018-04-16 11:40:36 +0000
Но Swift не делает никаких предположений о типе объектов: вы передаете ему необязательное значение, и он печатает его как таковое.
The date is Optional(2018-04-16 11:40:36 +0000)
Когда наш преобразователь увидит такой код:
- (NSString *)greetingForName:(NSString *)name {
return [NSString stringWithFormat: @"Hello there, %@.", name];
}
Это разумно развернет необязательный для вас.
func greeting(forName name: String?) -> String? {
return "Hello there, \(name ?? "")."
}
Попробуйте:
Что бы вы хотели видеть от Swiftify?
Видели ли вы какие-либо дела, которые хотели бы автоматизировать с помощью Swiftify? Дайте нам знать в комментариях ниже!
