Apa itu 'get' dan 'set' di Swift?

101

Saya belajar Swift dan saya membaca The Swift Programming Languagedari Apple, saya tidak memiliki latar belakang Objective C (hanya PHP, JS, dan lainnya tetapi tidak ada Obj C)

Pada halaman 24-25 saya melihat kode ini:

//...Class definition stuff...

var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
}

//...Class continues...

Bagian ini TIDAK ditentukan dalam buku dan saya tidak mengerti untuk apa itu.

Adakah yang bisa menjelaskan kepada saya apa yang mendapatkan dan mengatur ?

Tuan Web
sumber
2
Apakah Anda membaca hal 21 tentang pengambil / penyetel. Juga, 30 pgs pertama atau lebih adalah tur Swift dan bukan dokumentasi lengkap.
vol7ron
Jika Anda telah melakukan C ++ Anda dapat menghubungkan hal-hal ini dengan fungsi anggota pengambil dan penyetel kelas
CodingOnSteroid

Jawaban:

38

Itu sebenarnya dijelaskan tepat sebelum kode:

Selain properti sederhana yang disimpan, properti bisa memiliki getter dan setter.

class EquilateralTriangle: NamedShape {
    ...

Ketika beberapa kelas lain ingin mendapatkan variabel perimeter itu, mereka melakukan ini:

let someVar = myTriangle.perimeter

... Yang menyebutnya:

get{
    return 3.0 * self.sideLength
}

Dan dengan demikian pada dasarnya seperti jika pengontrol pemanggil melakukan ini:

let someVar = 3.0 * myTriangle.sideLength

Saat Anda menyetel variabel dari objek lain, akan terlihat seperti ini:

myTriangle.perimeter = 100

Yang memanggil kode di set{}blok:

set {
    sideLength = newValue / 3.0
}

Dan jadi seperti jika kelas yang mengatur variabel telah melakukan ini:

myTriangle.sideLength = 100/3.0

Ini benar-benar hanya untuk kenyamanan - Anda dapat memanggil ini dari kode lain tanpa harus selalu membagi atau mengalikan dengan 3, karena itu dilakukan tepat sebelum menetapkan variabel dan tepat sebelum Anda mendapatkan variabel.

Di Swift, kita bisa memiliki properti yang dihitung saat didapat dan bisa melakukan sesuatu saat disetel. Kita juga bisa melakukan ini di Objective-C:

// .h
@property (nonatomic) double perimeter;

//.m

- (double)perimeter
{
    return self.sideLength * 3.0;
}
- (void)setPerimeter:(double)perimeter
{
    self.perimeter = perimeter; // In Swift, this is done automatically.
    self.sideLength = perimeter / 3.0;
}
Urungkan
sumber
108

Pengambilan dan pengaturan variabel dalam kelas mengacu pada pengambilan ("mendapatkan") atau mengubah ("pengaturan") isinya.

Pertimbangkan variabel memberskelas family. Secara alami, variabel ini harus berupa bilangan bulat, karena sebuah keluarga tidak pernah bisa terdiri dari dua titik sesuatu orang.

Jadi Anda mungkin akan melanjutkan dengan mendefinisikan membersvariabel seperti ini:

class family {
   var members:Int
}

Ini, bagaimanapun, akan memberi orang yang menggunakan kelas ini kemungkinan untuk mengatur jumlah anggota keluarga menjadi sekitar 0 atau 1. Dan karena tidak ada yang namanya keluarga 1 atau 0, ini sangat disayangkan.

Di sinilah pengambil dan penyetel masuk. Dengan cara ini Anda dapat memutuskan sendiri bagaimana variabel dapat diubah dan nilai apa yang dapat mereka terima, serta memutuskan konten apa yang mereka kembalikan.

Kembali ke kelas keluarga kita, mari pastikan tidak ada yang dapat menyetel membersnilainya menjadi kurang dari 2:

class family {
  var _members:Int = 2
  var members:Int {
   get {
     return _members
   }
   set (newVal) {
     if newVal >= 2 {
       _members = newVal
     } else {
       println('error: cannot have family with less than 2 members')
     }
   }
  }
}

Sekarang kita dapat mengakses membersvariabel seperti sebelumnya, dengan mengetik instanceOfFamily.members, dan berkat fungsi setter, kami juga dapat menetapkan nilai itu seperti sebelumnya, dengan mengetik, misalnya: instanceOfFamily.members = 3. Apa yang berubah, bagaimanapun, adalah kenyataan bahwa kita tidak dapat mengatur variabel ini menjadi lebih kecil dari 2 lagi.

Perhatikan pengenalan _membersvariabel, yang merupakan variabel aktual untuk menyimpan nilai yang kita tetapkan melalui membersfungsi penyetel. Yang asli memberssekarang telah menjadi properti yang dihitung, artinya itu hanya bertindak sebagai antarmuka untuk menangani variabel aktual kita.

Markus Buhl
sumber
members==> count, numberOfMembers; var members : Set<Person>??
GoZoner
1
set (newVal) { ... }, newVal tersirat, begitu set { _members = newVal }juga benar.
AndreasHassing
4
Perhatikan bahwa variabel seperti _membersharus bersifat pribadi, jika tidak, perintah instanceOfFamily._members=1akan disetel instanceOfFamily.memberske nilai di bawah 2
Daniel
Sepertinya parameter default diberi nama newValuedi Swift 4 - docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Nolan Amy
18

Pertanyaan sederhana harus diikuti dengan jawaban yang singkat, sederhana dan jelas.

  • Saat kita mendapatkan nilai properti, ia menjalankan get{}bagiannya.

  • Saat kita menetapkan nilai ke properti, ia mengaktifkan set{}bagiannya.

PS. Saat menyetel nilai ke properti, SWIFT secara otomatis membuat konstanta bernama "newValue" = nilai yang kami tetapkan. Setelah konstanta "newValue" dapat diakses di bagian properti set{}.

Contoh:

var A:Int = 0
var B:Int = 0

var C:Int {
get {return 1}
set {print("Recived new value", newValue, " and stored into 'B' ")
     B = newValue
     }
}

//When we are getting a value of C it fires get{} part of C property
A = C 
A            //Now A = 1

//When we are setting a value to C it fires set{} part of C property
C = 2
B            //Now B = 2
Pepatah
sumber
1
apakah wajib menetapkan nilai default bagi anggota untuk mengakses dari luar kelas. saya punya masalah ini diperbaiki ketika saya menetapkan nilai default untuk itu kelas UserBean: NSObject {var user_id: String? = nil} mengaksesnya seperti berikut, biarkan pengguna: UserBean = UserBean () user.user_id = "23232332"
Amr Angry
1

Anda harus melihat Properti Terhitung

Dalam contoh kode Anda, perimeteradalah properti yang tidak dicadangkan oleh variabel kelas, sebagai gantinya nilainya dihitung menggunakan getmetode dan disimpan melalui setmetode - biasanya disebut sebagai pengambil dan penyetel .

Saat Anda menggunakan properti seperti ini:

var cp = myClass.perimeter

Anda memanggil kode yang terdapat dalam getblok kode, dan ketika Anda menggunakannya seperti ini:

myClass.perimeter = 5.0

Anda memanggil kode yang terdapat dalam setblok kode, di mana newValuesecara otomatis diisi dengan nilai yang diberikan di sebelah kanan operator penugasan.

Properti yang dihitung bisa menjadi readwrite jika getter dan setter ditentukan, atau readonly jika getter saja yang ditentukan.

Antonio
sumber
0

variabel mendeklarasikan dan memanggil seperti ini di kelas

class X {
    var x: Int = 3

}
var y = X()
print("value of x is: ", y.x)

//value of x is:  3

sekarang Anda ingin memprogram untuk membuat nilai default x lebih dari atau sama dengan 3. Sekarang ambil kasus hipotetis jika x kurang dari 3, program Anda akan gagal. jadi, Anda ingin orang-orang memasukkan 3 atau lebih dari 3. Swift membuatnya mudah bagi Anda dan penting untuk memahami cara mengencangkan nilai variabel ini karena mereka akan banyak digunakan dalam pengembangan iOS. Sekarang mari kita lihat bagaimana get dan set akan digunakan di sini.

class X {
    var _x: Int = 3
    var x: Int {
        get {
            return _x
        }
        set(newVal) {  //set always take 1 argument
            if newVal >= 3 {
             _x = newVal //updating _x with the input value by the user
            print("new value is: ", _x)
            }
            else {
                print("error must be greater than 3")
            }
        }
    }
}
let y = X()
y.x = 1
print(y.x) //error must be greater than 3
y.x = 8 // //new value is: 8

jika Anda masih ragu, ingat saja, penggunaan get dan set adalah untuk memperbarui variabel apa pun seperti yang kita inginkan. get dan set akan memberi Anda kendali yang lebih baik untuk mengatur logika Anda. Alat yang kuat karenanya tidak mudah dimengerti.

saran
sumber