Tag logo

Short notes about Swift

Aug 11, 2024/
#swift
/-15 min

Yaşayan Yazı, bir yerimden uydurduğum bir terimdir ve ileriki dönemde içeriği zenginleşebilecek ama şu anki haliyle de faydalı olabilecek yazıları belirtir.

Variables

  • Değişkenler için

    var
    , constant için
    let
    kullan.

    1var age = 24
    2let PI = 3.14159
  • Temel değerlerin tipler type inference ile otomatik algılanır. Ancak initialize edilmiyorsa type annotation verilmelidir.

    1let year = 1999
    2let year: Int = 1999
    3var name: String
    4name = "Enes"

Data Types

String

1var name = "Enes"
  • Çok satır metinler için üç tırnak kullan. Yeni satıra inmesini engellemek için satır sonuna

    \
    ekle.

    1var address = """
    2Y Mahallesi \
    3X Sokak No:1 Kat:5
    4Kadıköy/Türkiye
    5"""
    Y Mahallesi X Sokak No:1 Kat:5
    Kadıköy/Türkiye
  • Dinamik string'ler için string interpolation kullan.

    1// example 1:
    2var score = 85
    3var str = "Your score was \(score)"
    4// example 2:
    5var greeting  = "Hi, \(user ?? "Anonymous")"
  • String'in boş olup olmadığını kontrol etmek için

    .isEmpty()
    kullan.

Integer

1var age = 24
2var population = 8_000_000

Float and Double

1let justOverOneMillion = 1_000_000.000_000_1
2let PI: Float = 3.14159
  • Varsayılan noktalı değer tipi Double'dır. Float oluşturmak için tip tanımlamalıyız.
  • Int bir değerle toplarken otomatik tür dönüşümü yapılmaz. Bunu yerine Double() kullanılabilir.
    1let num1 = 1.2
    2let num2 = 5
    3print(num1 + Double(num2))

Boolean

1var isSuccess = true
6.2

Collections

Array

1var emptyArray = [Int]()
2var emptyArray2: [Int] = []
3var emptyArray3: Array<Float> = Array()
4var emptyArray4 = Array<Int>()
5let beatles = ["John Lennon", "Paul McCartney", "George Harrison", "Ringo Starr"]
6let numbers: [Int] = [1, 10, 5, 7]
  • Array annotation'ları

    [String]
    ve
    [Boolean]
    gibi tanımlanabilir.

  • Değer okunurken köşeli parantez kullanımı uygulanır ve yoksa hata verir.

    1let beatles = ["John Lennon", "Paul McCartney", "George Harrison", "Ringo Starr"]
    2beatles[1]
    3beatles[12] // crash verir
  • Sona değer eklemek için

    append
    metodu kullanılır. Birden fazla değer eklemek için
    contentsOf
    parametresi kullanılır. Belirli indekse eleman eklemek istersek
    insert
    metodu kullanılır.

    1var students = ["Ben", "Ivy", "Jordell"]
    2students.append("Maxime")
    3students.append(contentsOf: ["Shakia", "William"])
    4students.insert("Liam", at: 3)
    5print(students)
    ["Ben", "Ivy", "Jordell", "Liam", "Maxime", "Shakia", "William"]
  • Eleman silmek için

    remove
    ve
    removeLast
    kullanılır.

    1students.remove(at: 0)
    2students.removeLast()
    3print(students)
    ["Ivy", "Jordell", "Liam", "Maxime", "Shakia"]
  • Array'in slice etmek için range operatör kullanılabilir.

    1let names = ["Piper", "Alex", "Suzanne", "Gloria"]
    2print(names[1...3])
    3print(names[2...])
    ["Alex", "Suzanne", "Gloria"]
    ["Suzanne", "Gloria"]
  • İki array'i birleştirmek için artı operatörü kullanılabilir. Bu operator overloading olarak geçer.

    1let firstHalf = ["John", "Paul"]
    2let secondHalf = ["George", "Ringo"]
    3let beatles = firstHalf + secondHalf

Set

1var emptySet1 = Set<String>()
2var emptySet2: Set<String> = Set()
3let colors = Set(["red", "green", "blue", "red", "blue"])
4print(colors)
["red", "green", "blue"]
  • Unordered'dır ve öğeler benzersizdir. Bu sayede arama işlemleri çok hızlı gerçekleşir.
  • Tanımlamak için
    Set()
    fonksiyonu kullanılır.

Tuple

1let name = (first: "Taylor", last: "Swift")
  • Birkaç değeri tek değerde saklamanıza izin verir.
  • Boyutu sabittir yani öğe eklenemez ve çıkarılamaz. Ancak değerler değiştirilebilir.
  • Dictionary'den farklı olarak bir değerin var olduğu garantidir ve boyutu büyüyemez.
  • Erişmek için index ve key kullanılır.
    1print(name.0)
    2print(name.first)

Dictionary

1var emptyDict1 = [String: String]()
2var emptyDict2: [String: String] = [:]
3var emptyDict3 = Dictionary<String, Int>()
4let person = [
5  "name": "Enes Başpınar",
6  "aeg": 24
7]
8var responseMessages = [
9  200: "OK",
10  403: "Access forbidden",
11  404: "File not found",
12  500: "Internal server error"
13]
  • Değer okunurken key yoksa
    nil
    yerine varsayılan değer döndürülebilir.
    1favoriteIceCream["Charlotte", default: "Unknown"]

Enum(eration)

1enum Result {
2  case success
3  case failure
4}
  • İlişkili değerleri bir arada tutar.

  • Değer olarak kullanırken tip tanımlanmışsa

    enum
    ismini kullanmaya gerek yoktur.

    1var result: Result = Result.success;
    2var result2: Result = .success;
  • Enum değerlerine raw index ile de erişebiliriz.

    1enum Planet: Int {
    2  case mercury = 1
    3  case venus
    4  case earth
    5  case mars
    6}
    7
    8let earth = Planet(rawValue: 3)
  • Enum değerleri ilişkili değerleri de depolayabilir.

    1enum Activity {
    2  case bored
    3  case running(destination: String)
    4  case talking(topic: String)
    5  case singing(volume: Int)
    6}
    7
    8let talking = Activity.talking(topic: "football")
  • Enum değerlerini karşılaştırılabilir hale getirmek için

    Comparable
    protokolü kullanılabilir.

    1enum Sizes: Comparable {
    2  case small
    3  case medium
    4  case large
    5}
    6
    7print(Sizes.small < Sizes.large)

Conditions

  • String'lerde alfabetik sıra olduğu için büyüktür küçüktür kullanılabilir. Örneğin
    "Taylor" <= "Swift"
    .

If else

1let firstCard = 11
2let secondCard = 10
3
4if firstCard + secondCard == 2 {
5  print("Aces – lucky!")
6} else if firstCard + secondCard == 21 {
7  print("Blackjack!")
8} else {
9  print("Regular cards")
10}

Ternary operator

1print(isLoggedIn ? "Welcome." : "Please login.")

Switch

1switch weather {
2case "rain":
3  print("Bring an umbrella")
4case "snow":
5  print("Wrap up warm")
6case "sunny":
7  print("Wear sunscreen")
8  fallthrough
9default:
10  print("Enjoy your day!")
11}
  • Eğer altındaki case'e devam etmesi için

    fallthrough
    kullanılabilir.

  • Belirli değer aralığında mı diye kontrol etmek için

    range
    operatör kullanılabilir.
    1..<5
    ve
    1...5
    arasındaki fark son değerin dahil edilip edilmediğidir.

    1let score = 85
    2
    3switch score {
    4case 0..<50:
    5  print("You failed badly.")
    6case 50..<85:
    7  print("You did OK.")
    8default:
    9  print("You did great!")
    10}

Loops

For

1// example 1:
2for number in 1...5 {
3  print("Number is \(number)")
4}
5// example 2:
6let names = ["Sterling", "Cyril", "Lana", "Ray", "Pam"]
7for _ in names {
8    print("[CENSORED] is a secret agent!")
9}
  • Array iterate etmek için

    in
    opeatörü kullanılabilir.

    1let albums = ["Red", "1989", "Reputation"]
    2
    3for album in albums {
    4  print("\(album) is on Apple Music")
    5}

While

1var number = 1
2
3while number <= 4 {
4  print(number)
5  number += 1
6}
1
2
3
4

Repeat (aka Do-While)

1var number = 1
2
3repeat {
4    print(number)
5    number += 1
6} while number < 1
1

Functions

1func square(number: Int) -> Int {
2  return number * number
3}
4
5let result = square(number: 8)
  • Fonksiyon tek bir ifade içeriyorsa

    return
    atlanabilir.

    1func isUppercase(string: String) -> Bool {
    2  string == string.uppercased()
    3}
    4
    5func greet(name: String) -> String {
    6  name == "Taylor Swift" ? "Oh wow!" : "Hello, \(name)"
    7}
  • Birden çok değer döndürmek istiyorsak tuple kullanabiliriz.

    1func getUser() -> (firstName: String, lastName: String) {
    2  return (firstName: "Taylor", lastName: "Swift")
    3  // ya da return ("Taylor", "Swift")
    4}
    5
    6let (firstName, lastName) = getUser()
    7print("Name: \(firstName) \(lastName)")
    Name: Taylor Swift
  • Parametrelere fonksiyon çalıştırırken kullanmak üzere label atayabiliriz.

    1func sayHello(to name: String) {
    2  print("Hello, \(name)!")
    3}
    4
    5sayHello(to: "Taylor")
    Hello, Taylor!
  • Parametre label'ını es geçmek için

    _
    kullanılabilir.

    1func greet(_ person: String, nicely: Bool = true) {
    2    if nicely == true {
    3        print("Hello, \(person)!")
    4    } else {
    5        print("Oh no, it's \(person) again...")
    6    }
    7}
    8
    9greet("Taylor")
    10greet("Taylor", nicely: false)
    Hello, Taylor!
    Oh no, it's Taylor again...
  • Variadic fonksiyon parametresi tanımlamak için tipinin sonuna

    ...
    eklenir. Parametre gönderilmezse değeri
    []
    olur.

    1func square(_ numbers: Int...) {
    2  for number in numbers {
    3    print("\(number) squared is \(number * number)")
    4  }
    5}
    6
    7square(1, 2, 3, 4, 5)
    1 squared is 1
    2 squared is 4
    3 squared is 9
    4 squared is 16
    5 squared is 25
  • Fonksiyon çalışırken hata fırlatmak için

    throws
    keyword kullanılabilir.

    1enum LoginErrors: Error {
    2  case badUsername
    3  case badPassword
    4}
    5
    6func login(username: String, password: String) throws -> Bool {
    7  if username.isEmpty { throw LoginErrors.badUsername }
    8  if password.isEmpty { throw LoginErrors.badPassword }
    9  return true
    10}
  • Fonksiyon parametreleri constant'tır. Parametre değiştiğinde orjinalinin de değişmesini istersek

    inout
    anahtar kelimesi kullanabiliriz.

    1func doubleInPlace(number: inout Int) {
    2  return number *= 2
    3}
    4
    5var myNum = 10
    6doubleInPlace(number: &myNum)
    7print(myNum)
    20

Closure

1{ (parameters) -> returnType in
2   // statements
3}
  • İsmi olmayan özel bir fonksiyon türüdür.

  • Değişkene atanabilir.

    1var greet = {
    2  print("Hello, World!")
    3}
    4greet()
  • Parametre alabilir. Fonksiyondan farklı olarak çağırırken parametre adını vermek gerekmez.

    1let greetUser = { (name: String)  in
    2    print("Hey there, \(name).")
    3}
    4
    5greetUser("Delilah")
  • Değer döndürebilir.

    1// usage 1:
    2var findSquare = { (num: Int) -> (Int) in
    3  var square = num * num
    4  return square
    5}
    6
    7// usage 2:
    8var findSquare = { (num: Int) -> Int in num * num }
    9
    10// usage 3:
    11var findSquare: (Int) -> Int = { num in num * num }
    12
    13// usage 4:
    14var findSquare: (Int) -> Int = { $0 * $0 }
    15
    16var result = findSquare(3)
  • Başka fonksiyona parametre olarak iletilebilir.

    1func grabLunch(search: () -> ()) {
    2  search()
    3}
    4
    5grabLunch(search: {
    6  print("Alfredo's Pizza: 2 miles away")
    7})
  • Fonksiyonun son parametresi closure ise trailing closure dediğimiz özel sözdizimi kullanabilir.

    1func grabLunch(message: String = "", search: () -> ()) {
    2  if (message != "") {
    3  print(message)
    4  }
    5  search()
    6}
    7
    8grabLunch(message:"Let's go out for lunch")  {
    9  print("Alfredo's Pizza: 2 miles away")
    10}
    11
    12grabLunch {
    13  print("Alfredo's Pizza: 2 miles away")
    14}
    Let's go out for lunch
    Alfredo's Pizza: 2 miles away
  • Referans tiplidir.

  • Tanımlandığı bağlamda bulunan değişkenlerin referanslarını saklar.

    1func travel() -> (String) -> Void {
    2    var counter = 1
    3
    4    return {
    5        print("\(counter). I'm going to \($0)")
    6        counter += 1
    7    }
    8}
    9
    10let makeTravel = travel()
    11makeTravel("London")
    12makeTravel("London")
    13makeTravel("London")

Error handling

  • Hata fırlatabilecek bir kod çalıştıracaksak

    do
    bloğu içinde kullanmalıyız. Hata fırlatabilecek fonksiyonun başına
    try
    konur. Hata fırlattığında
    catch
    'e düşer.

    1enum PasswordError: Error {
    2  case obvious
    3}
    4
    5func checkPassword(_ password: String) throws -> Bool {
    6  if password == "password" {
    7    throw PasswordError.obvious
    8  }
    9
    10  return true
    11}
    12
    13do {
    14  try checkPassword("password")
    15  print("That password is good!")
    16} catch {
    17  print("You can't use that password.")
    18}
  • Başarısız olduğunda

    nil
    dönmesini isterseniz
    try?
    kullanabilirsiniz.

    1if let result = try? checkPassword("password") {
    2  print("Result was \(result)")
    3} else {
    4  print("D'oh.")
    5}

Struct

  • Özel değişken tipi oluşturmanın en yaygın yoludur.

    1struct Sport {
    2    var name: String
    3}
    4
    5var tennis = Sport(name: "Tennis")
    6print(tennis.name)
    7tennis.name = "Lawn tennis"
    8print(tennis.name)
    Tennis
    Lawn tennis

Initializer

  • Varsayılan olarak memberwise initializer ile gelir. Manuel işlemek için

    init()
    kullanabiliriz.

  • self
    mevcut instance'a işaret eder.
    init
    haricinde kullanmamalıyız.

    1// usage 1: memberwise
    2struct Employee {
    3    var name: String
    4    var yearsActive = 0
    5}
    6
    7let roslin = Employee(name: "Laura Roslin")
    8let adama = Employee(name: "William Adama", yearsActive: 45)
    9
    10// usage 2:
    11struct Employee {
    12    var name: String
    13    var yearsActive = 0
    14
    15    init() {
    16        self.name = "Anonymous"
    17        print("Creating an anonymous employee…")
    18    }
    19}
    20
    21var roslin = Employee()
    22roslin.name = "Laura Roslin"
    23
    24// usage 3:
    25struct Employee {
    26    var name: String
    27    var yearsActive = 0
    28
    29    init(name: String) {
    30        self.name = name
    31    }
    32}
    33
    34var roslin = Employee(name: "Laura Roslin")
    Creating a new user!

Property

  • Eğer bir property'nin ilk erişildiğinde hesaplanmasını istiyorsak

    lazy
    anahtar kelimesini kullanabiliriz. Hesaplama maliyeti nesne oluşturulurken atlanmış olur. Sonraki her çağrılışta hesaplanan sonucu bellekten döndürür.

    1struct FamilyTree {
    2    init() {
    3        print("Creating family tree!")
    4    }
    5}
    6
    7struct Person {
    8    var name: String
    9    lazy var familyTree = FamilyTree()
    10
    11    init(name: String) {
    12        self.name = name
    13    }
    14}
    15
    16let ed = Person(name: "Ed")
    17let edFamilyTree = ed.familyTree
    Creating family tree!

Computed property

  • Başka bir property değerine göre hesaplanan property'lerdir. Ağır hesaplamalar için metod kullanmak daha iyidir.

    1struct Sport {
    2  var name: String
    3  var isOlympicSport: Bool
    4
    5  var olympicStatus: String {
    6    return  isOlympicSport ? "\(name) is an Olympic sport" : "\(name) is not an Olympic sport"
    7  }
    8
    9  func play() {
    10    // ...
    11  }
    12}
    13
    14let chessBoxing = Sport(name: "Chessboxing", isOlympicSport: false)
    15print(chessBoxing.olympicStatus)

Static property

1struct Student {
2    static var classSize = 0
3    var name: String
4
5    init(name: String) {
6        self.name = name
7        Student.classSize += 1
8    }
9}
10let ed = Student(name: "Ed")
11let taylor = Student(name: "Taylor")
12print(Student.classSize)
2

Property observe

  • Değeri değiştiğinde ve değişmeden önce bir işlem gerçekleştirmek için

    didSet
    ve
    willSet
    kullanılır.

    1struct Progress {
    2    var task: String
    3    var amount: Int {
    4        didSet {
    5            print("\(task) is now \(amount)% complete")
    6        }
    7    }
    8}
    9
    10var progress = Progress(task: "Loading data", amount: 0)
    11progress.amount = 30
    12progress.amount = 80
    13progress.amount = 100
    Loading data is now 30% complete
    Loading data is now 80% complete
    Loading data is now 100% complete

Mutating

  • Varsayılan olarak metotların içinde property değiştirilemez yani constant struct'tır. Buna izin vermek için

    mutating
    anahtar kelimesi kullanılır.

    1struct Person {
    2  var name: String
    3
    4  mutating func makeAnonymous() {
    5    name = "Anonymous"
    6  }
    7}
    8
    9var person = Person(name: "Ed")
    10person.makeAnonymous()

Access control

  • public
    ve
    private
    property ve metodlara nereden erişilebileceğini tanımlar.

    1struct Person {
    2  private var id: String
    3
    4  init(id: String) {
    5    self.id = id
    6  }
    7
    8  func identify() -> String {
    9    return "My social security number is \(id)"
    10  }
    11}

Class

1class Dog {
2    var name: String
3    var breed: String
4
5    init(name: String, breed: String) {
6        self.name = name
7        self.breed = breed
8    }
9}
10
11let poppy = Dog(name: "Poppy", breed: "Poodle")
  • Referans tiplidirler yani instance'ların referansı aynıdır.

  • Inheritance yapmak için ilgili sınıf annotation ile belirtilebilir.

    1class Dog {
    2  var name: String
    3  var breed: String
    4
    5  init(name: String, breed: String) {
    6    self.name = name
    7    self.breed = breed
    8  }
    9}
    10
    11class Poodle: Dog {
    12  init(name: String) {
    13    super.init(name: name, breed: "Poodle")
    14  }
    15}
  • Inherit edilmemesini istediğimiz fonksiyonları

    final
    ile tanımlayabiliriz. Kritik bir şey yapıyorsanız override edilmemesi için bunu uygulayabilirsiniz.

  • Metodu override etmek için

    override
    anahtar kelimesi kullanılır.

    1class Dog {
    2    func makeNoise() {
    3        print("Woof!")
    4    }
    5}
    6
    7class Poodle: Dog {
    8    override func makeNoise() {
    9        print("Yip!")
    10    }
    11}
    12
    13let poppy = Poodle()
    14poppy.makeNoise()
    Yip!
  • Nesne yok edildiğinde bir işlem yapmak için deinitializer tanımlanabilir.

    1class Person {
    2    var name = "John Doe"
    3
    4    init() {
    5        print("\(name) is alive!")
    6    }
    7
    8    deinit {
    9      print("\(name) is no more!")
    10    }
    11
    12    func printGreeting() {
    13        print("Hello, I'm \(name)")
    14    }
    15}
    16
    17for _ in 1...3 {
    18    let person = Person()
    19    person.printGreeting()
    20}
    John Doe is alive!
    Hello, I'm John Doe
    John Doe is no more!
    John Doe is alive!
    Hello, I'm John Doe
    John Doe is no more!
    John Doe is alive!
    Hello, I'm John Doe
    John Doe is no more!
  • Sınıf sabit olarak oluşturulduğunda bile bir sınıf üzerindeki property'ler değiştirebilir. Dolayısıyla

    mutating
    anahtar kelimesine ihtiyacı yok.

  • Bir property'nin immutable olması için

    let
    ile constant olarak tanımlanabilir.

Protocol

  • Bir şeyin hangi property ve metodlara sahip olması gerektiğini tanımlar. Java interface'lerine çok benzerdir.

    1protocol Purchaseable {
    2  var name: String { get set }
    3}
    4
    5struct Book: Purchaseable {
    6  var name: String
    7  var author: String
    8}
    9
    10struct Movie: Purchaseable {
    11  var name: String
    12  var actors: [String]
    13}
    14
    15struct Car: Purchaseable {
    16  var name: String
    17  var manufacturer: String
    18}
    19
    20func buy(_ item: Purchaseable) {
    21  print("I'm buying \(item.name)")
    22}
  • Protocol'lerde inheritance destekler.

    1// bad usage:
    2protocol Computer {
    3    var price: Double { get set }
    4    var weight: Int { get set }
    5    var cpu: String { get set }
    6    var memory: Int { get set }
    7    var storage: Int { get set }
    8}
    9
    10protocol Laptop {
    11  var price: Double { get set }
    12  var weight: Int { get set }
    13  var cpu: String { get set }
    14  var memory: Int { get set }
    15  var storage: Int { get set }
    16  var screenSize: Int { get set }
    17}
    18
    19// good usage:
    20protocol Product {
    21  var price: Double { get set }
    22  var weight: Int { get set }
    23}
    24
    25protocol Computer: Product {
    26  var cpu: String { get set }
    27  var memory: Int { get set }
    28  var storage: Int { get set }
    29}
    30
    31protocol Laptop: Computer {
    32  var screenSize: Int { get set }
    33}

Extension

  • Orjinalini bozmadan mevcuttaki tiplere ekstra metodlar eklemenize izin verir.

    1extension Int {
    2  var isEven: Bool {
    3    return self % 2 == 0
    4  }
    5
    6  func squared() -> Int {
    7    return self * self
    8  }
    9}
    10
    11let number = 8
    12print(number.squared())
    13print(number.isEven)
  • Protokoldeki metodlara varsayılan implementasyon vermek için protocol extension kullanılabilir. Protocol inherit eden her yeri etkiler.

    1extension Collection {
    2  func summarize() {
    3    print("There are \(count) of us:")
    4
    5    for name in self {
    6      print(name)
    7    }
    8  }
    9}
    10
    11let pythons = ["Eric", "Graham", "John", "Michael", "Terry", "Terry"]
    12let beatles = Set(["John", "Paul", "George", "Ringo"])
    13
    14pythons.summarize()
    15beatles.summarize()

Optionals

  • Bir değerin olmayabileceğini (

    nil
    ) belirtir.

    1var age: Int? = nil
    2age = 38
  • Optional değerler direk kullanılmaz ve unwrapping yapmak gerekir.

    if let
    ve
    guard let
    ile yapılabilir:

    1func getUsername() -> String? { "Taylor" }
    2
    3if let username = getUsername() {
    4  print("Username is \(username)")
    5} else {
    6  print("No username")
    7}
    1func greet(_ name: String?) {
    2  guard let unwrapped = name else {
    3    print("You didn't provide a name!")
    4    return
    5  }
    6
    7  print("Hello, \(unwrapped)!")
    8}
  • Bazen bir değerin nil olmadığından eminsinizdir. Bu durumda force unwrapping kullanılabilir.

    !
    aynı zamanda crash operator olara isimlendirilir.

    1// usage 1:
    2enum Direction: CaseIterable {
    3    case north, south, east, west
    4}
    5let randomDirection = Direction.allCases.randomElement()!
    6
    7// usage 2:
    8enum Direction: CaseIterable {
    9  case north, south, east, west
    10
    11  static func random() -> Direction {
    12    Direction.allCases.randomElement()!
    13  }
    14}
    15let randomDirection = Direction.allCases.randomElement()!
  • Bir değerin sadece tanımlarken nil olduğunu ancak kullanırken her zaman dolu olacağını biliyorsak direk unwrapped optional olarak tanımlayabiliriz.

    1let age: Int! = nil
  • Değer nil olduğunda varsayılan belirtmek için

    nil coalescing
    kullanılır. Birden fazla zincirlenebilir.

    1func username(for id: Int) -> String? {
    2  return id == 1 ? "Taylor Swift" : nil
    3}
    4
    5let user = username(for: 15) ?? "Anonymous"
  • Nil olabilecek bir nesneden değer okuyacaksak crash almamak için

    optional chaining
    kullanılabilir.

    1let names = ["Vincent": "van Gogh", "Pablo": "Picasso", "Claude": "Monet"]
    2let surnameLetter = names["Vincent"]?.first?.uppercased()
  • Initializer'da nesne oluşturma enasında problem yaşadığınızda nil dönmek isterseniz

    init?
    kullanabilirsiniz.

    1struct Employee {
    2  var username: String
    3  var password: String
    4
    5  init?(username: String, password: String) {
    6    guard password.count >= 8 else { return nil }
    7    guard password.lowercased() != "password" else { return nil }
    8
    9    self.username = username
    10    self.password = password
    11  }
    12}