Irbisa · Шпаргалка
Основы Swift
Переменные, optional, типы, control flow, замыкания, value vs reference
В чём разница между
letиvarв Swift?let name = "Ada"// name = "Grace" // error: cannot assign to a let constant var attempts = 0attempts += 1 // fine…Что такое Optional в Swift, как он устроен и как его безопасно развернуть?
var nickname: String? = "Ada" if let nickname { print(nickname.uppercased()) // runs only when there is a value}…В чём разница между
if letиguard let, и когда стоит использоватьguard?struct User { let name: String; let isActive: Bool } func greet(_ user: User?) { guard let user, user.isActive else { print("nothing to greet") return // else has to leave the scope…Что выведет этот код и почему в первой строке появляется
Optional("Ada")?let name: String? = "Ada"let bonus: Int? = 5 print("Hello, \(name)")print("Hello, \(name ?? "guest")")print(bonus ?? 0 + 1)Чем
String?отличается отString!и почему@IBOutlet, объявленный какUILabel!, падает с «unexpectedly found nil»?В чём разница между типами-значениями и ссылочными типами в Swift?
struct Point { var x: Int }let a = Point(x: 1)var b = a // an independent copyb.x = 99print(a.x) // 1…В чём разница между
==и===в Swift?struct Point: Equatable { var x: Int }print(Point(x: 1) == Point(x: 1)) // true: same content final class Box {}let a = Box()let b = Box()…В чём разница между
is,as,as?иas!?class Animal {}final class Dog: Animal { func bark() { print("woof") } } let pets: [Animal] = [Dog(), Animal()]for pet in pets { print(pet is Dog) // true, then false…В чём разница между
AnyиAnyObject?protocol Delegate: AnyObject {} // class-only protocol final class Screen { weak var delegate: Delegate? // weak needs a class-bound type}…В чём разница между
Array,SetиDictionary, и как выбрать нужную коллекцию?var tags = ["swift", "ios", "swift"]tags.insert("ui", at: 0) // O(n): shifts every element let unique = Set(tags) // 3 elements, order unspecifiedprint(unique.contains("ios")) // O(1) on average…В чём разница между
map,compactMapиflatMapв Swift?let raw: [String?] = ["swift", nil, "ios"]let lengths = raw.compactMap { $0?.count } // [5, 3]let withNils = raw.map { $0?.count } // [Int?]: 5, nil, 3 let numbers = ["1", "two", "3"].compactMap(Int.init) // [1, 3]let flat = [[1, 2], [3]].flatMap { $0 } // [1, 2, 3]…Что умеет
switchв Swift, чего не умеетswitchв стиле C?enum Download { case idle case running(progress: Double) case failed(retryIn: Int)}…Почему в Swift нельзя сложить
IntиDoubleи чем отличаютсяFloat,DoubleиCGFloat?let count = 7let total = 10// let ratio = count / total * 100.0 // error: Int and Double do not mixlet ratio = Double(count) / Double(total) * 100 // 70.0 let half = 1 / 2 // 0: both literals default to Int…Что такое замыкание в Swift и это тип-значение или ссылочный тип?
func makeCounter() -> () -> Int { var count = 0 return { // captures count and keeps it alive count += 1 return count }…В чём разница между
weakиunownedи когда в замыкании нужен[weak self]?final class ProfileViewModel { var onUpdate: (() -> Void)? var title = "" func start() { // self owns onUpdate: capturing self strongly would be a retain cycle…Как устроена обработка ошибок в Swift:
throws,try,try?,try!,do/catchиResult?enum AuthError: Error { case invalidCredentials case throttled(retryAfter: Int)} struct User { let email: String }…Что выведет этот код и почему изменение элемента копии меняет и исходный массив?
final class Item { var title: String init(title: String) { self.title = title }} var original = [Item(title: "A"), Item(title: "B")]var copy = originalcopy[0].title = "Changed"copy.append(Item(title: "C")) print(original[0].title)print(original.count)Найдите баг: нажатие «Добавить» на товар, который уже лежит в корзине, никогда не увеличивает его количество.
struct CartItem { let name: String var quantity: Int} final class Cart { private(set) var items: [CartItem] = [] func add(_ name: String) { if var existing = items.first(where: { $0.name == name }) { existing.quantity += 1 } else { items.append(CartItem(name: name, quantity: 1)) } }}Что выведет этот код и что меняет список захвата
[value]?func demo() { var value = 1 let captured = { print("captured:", value) } let copied = { [value] in print("capture list:", value) } value = 2 captured() copied()} demo()Что выведет этот код и когда именно выполняется блок
defer?func demo() { var counter = 0 func next() -> Int { defer { counter += 1 } return counter } print(next(), counter)} func order() { defer { print("A") } defer { print("B") } print("C")} demo()order()Что делает
inoutи чем это отличается от передачи экземпляра класса?func normalize(_ values: inout [Double]) { guard let maxValue = values.max(), maxValue > 0 else { return } for i in values.indices { values[i] /= maxValue }} var samples = [2.0, 4.0, 8.0]…Почему в Swift нельзя написать
name[3]дляStringи что такоеSubstring?let s = "Cafe\u{301}" // "Café": 5 scalars, 4 charactersprint(s.count) // 4print(s.unicodeScalars.count) // 5print(s == "Café") // true // let c = s[3] // error: no Int subscript…let rest = items.dropFirst(), а затемrest[0]падает с «Index out of bounds», хотяrestне пустой. Почему?Три товара по 1.10 дают в чеке сумму 3.3000000000000003. Что пошло не так и в каком типе хранить деньги?
print(1.1 * 3) // 3.3000000000000003print(0.1 + 0.2 == 0.3) // falseprint(Int(4.35 * 100)) // 434, not 435 let priceCents = 110let totalCents = priceCents * 3 // 330, exact…В чём разница между
assert,preconditionиfatalErrorи какие из них работают в Release-сборке?assert(index >= 0, "negative index") // Debug only, not evaluated in Releaseprecondition(!items.isEmpty, "empty cart") // Debug and Release func make() -> Int { fatalError("unreachable") // returns Never, always traps}