struktur vs kelas dalam bahasa cepat

192

Dari buku Apple "Salah satu perbedaan paling penting antara struktur dan kelas adalah bahwa struktur selalu disalin ketika mereka diedarkan dalam kode Anda, tetapi kelas dilewatkan dengan referensi."

Adakah yang bisa membantu saya memahami apa artinya itu? Bagi saya, kelas dan struct tampaknya sama.

Manish Agrawal
sumber
3
Lihat perbedaan antara struct dan kelas di .NET: stackoverflow.com/a/13275/19100 , saya menduga Swift menggunakan semantik yang sama.
dalle
23
@jonrsharpe mungkin mudah bagi Anda? dapatkah Anda memberi saya jawabannya jika Anda tahu ini
Manish Agrawal
1
Referensi nilai vs bukan konsep OOP saja. Itu ada di C, seperti void my_func(int a)vs void my_func(int &a). Ini adalah pertanyaan pemrograman yang sangat mendasar. Baca lebih lanjut: stackoverflow.com/questions/373419/…
superarts.org

Jawaban:

473

Berikut ini contoh dengan a class. Perhatikan bagaimana ketika nama diubah, instance yang dirujuk oleh kedua variabel diperbarui. Bobsekarang Sue, di mana-mana yang Bobpernah dirujuk.

class SomeClass {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var aClass = SomeClass(name: "Bob")
var bClass = aClass // aClass and bClass now reference the same instance!
bClass.name = "Sue"

println(aClass.name) // "Sue"
println(bClass.name) // "Sue"

Dan sekarang dengan structkita melihat bahwa nilai-nilai disalin dan masing-masing variabel menjaga set nilainya sendiri. Ketika kami mengatur nama Sue, Bobstruct di aStructtidak bisa diubah.

struct SomeStruct {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var aStruct = SomeStruct(name: "Bob")
var bStruct = aStruct // aStruct and bStruct are two structs with the same value!
bStruct.name = "Sue"

println(aStruct.name) // "Bob"
println(bStruct.name) // "Sue"

Jadi untuk mewakili entitas kompleks stateful, a classmengagumkan. Tetapi untuk nilai yang hanya berupa pengukuran atau bit data terkait, a structlebih masuk akal sehingga Anda dapat dengan mudah menyalinnya dan menghitungnya atau memodifikasi nilai tanpa takut efek samping.

Alex Wayne
sumber
"Tetapi untuk nilai-nilai yang tidak lebih kompleks dari sekadar angka ..." Terima kasih untuk Alex ini
Mike Rapadas
7
@MichaelRapadas Numbers sebenarnya adalah struct di Swift.
Nikolai Ruhe
Bisakah Anda memperjelas ini aStruct and bStruct are two structs with the same value!membingungkan saya karena nilai-nilai variabel di dalam struct berbeda.
Julian Król
@ JulianKról A garis itu aStructdan bStructmemiliki nilai yang identik. Mereka berdua memiliki satu namebidang yang diatur "Bob". Tetapi mereka adalah dua struct yang berbeda. Ini terbukti pada baris berikutnya ketika Anda dapat mengubah nama salah satu struct, dan yang lainnya tetap tidak berubah.
Alex Wayne
Baru saja melewatkan tugas. Jelas, terima kasih. Mungkin terlalu panas di luar :-)
Julian Król
60

Kelas dan struktur dapat melakukan:

  • Tentukan properti untuk menyimpan nilai
  • Tetapkan metode untuk menyediakan fungsionalitas
  • Diperpanjang
  • Sesuai dengan protokol
  • Tentukan penginstalasi
  • Tentukan Subskrip untuk memberikan akses ke variabel mereka

Hanya kelas yang dapat melakukan:

  • Warisan
  • Ketik casting
  • Tentukan deinitialisers
  • Izinkan penghitungan referensi untuk banyak referensi.
Durul Dalkanat
sumber
32

structadalah tipe nilai. Ini berarti bahwa jika Anda menyalin contoh struktur ke variabel lain, itu hanya disalin ke variabel.

Contoh untuk Tipe Nilai

struct Resolution {
    var width = 2
    var height = 3
}

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd //assigning struct instance  to variable
println("Width of cinema instance is \(cinema.width)")//result is 1920
println("Width of hd instance is \(hd.width)")//result is 1920

cinema.width = 2048

println("Width of cinema instance is \(cinema.width)")//result is 2048
println("Width of hd instance is \(hd.width)")//result is 1920

Kelas adalah tipe referensi. Ini berarti bahwa jika Anda menetapkan instance kelas ke variabel, itu hanya akan menampung referensi ke instance dan bukan salinannya .

ashok vadivelu
sumber
5
+1 untuk "Jika Anda menetapkan instance kelas ke variabel lain, Ini hanya akan menampung referensi instance bukan salinan."
Saif
8

Jawaban di atas benar Saya harap jawaban saya akan membantu seseorang yang tidak mengerti jawaban di atas.

Nah di Swift Ada dua jenis objek

  1. Struct
  2. Kelas

Perbedaan utama di antara mereka adalah

  • Struct adalah nilai tipe
  • Kelas adalah tipe referensi

Misalnya kode di sini untuk mengerti dengan baik.

struct SomeStruct {
var a : Int;

init(_ a : Int) {
    self.a = a
}
}

class SomeClass {
var a: Int;

init(_ a: Int) {
    self.a = a
}

}
var x = 11

var someStruct1 = SomeStruct(x)
var someClass1 = SomeClass(x)

var someStruct2 = someStruct1
var someClass2 = someClass1

someClass1.a = 12
someClass2.a // answer is 12 because it is referencing to class 1     property a

someStruct1.a = 14
someStruct2.a // answer is 11 because it is just copying it not referencing it

Ini adalah perbedaan utama tetapi kami juga memiliki beberapa perbedaan.

Kelas

  1. Harus mendeklarasikan penginisialisasi (konstruktor)
  2. Memiliki deinitialisers
  3. Dapat mewarisi dari kelas lain

Struct

  1. Ini memiliki penginisialisasi gratis untuk Anda, Anda tidak perlu mendeklarasikan initaliser jika Anda melakukan inisialisasi gratis akan ditimpa oleh penginisialisasi yang Anda nyatakan
  2. Jangan punya deinitialiser
  3. Tidak dapat mewarisi dari struct lain
dara
sumber
7

Pertanyaan ini tampaknya duplikat tetapi terlepas dari, yang berikut ini akan menjawab sebagian besar kasus penggunaan:

  1. Salah satu perbedaan paling penting antara struktur dan kelas adalah bahwa struktur adalah tipe nilai dan selalu disalin ketika mereka diedarkan dalam kode Anda, dan kelas adalah tipe referensi dan diteruskan dengan referensi.

  2. Juga, kelas memiliki Warisan yang memungkinkan satu kelas mewarisi karakteristik yang lain.

  3. Properti Struct disimpan di Stack dan instance Class disimpan di Heap karenanya, kadang-kadang stack secara drastis lebih cepat daripada kelas.

  4. Struct mendapatkan initializer default secara otomatis sedangkan di Class, kita harus menginisialisasi.

  5. Struct aman utas atau tunggal pada suatu saat

Dan juga, Untuk meringkas perbedaan antara struct dan kelas, perlu untuk memahami perbedaan antara nilai dan tipe referensi.

  1. Saat Anda membuat salinan tipe nilai, itu menyalin semua data dari hal yang Anda salin ke variabel baru. Mereka adalah 2 hal yang terpisah dan mengubah satu tidak mempengaruhi yang lain.
  2. Saat Anda membuat salinan tipe referensi, variabel baru merujuk ke lokasi memori yang sama dengan yang Anda salin. Ini berarti bahwa mengubah yang satu akan mengubah yang lain karena keduanya merujuk ke lokasi memori yang sama. Kode contoh di bawah ini dapat diambil sebagai referensi.

// sampleplayground.playground

  class MyClass {
        var myName: String
        init(myName: String){
            self.myName = myName;
        }
    }

    var myClassExistingName = MyClass(myName: "DILIP")
    var myClassNewName = myClassExistingName
    myClassNewName.myName = "John"


    print("Current Name: ",myClassExistingName.myName)
    print("Modified Name", myClassNewName.myName)

    print("*************************")

    struct myStruct {
        var programmeType: String
        init(programmeType: String){
            self.programmeType = programmeType
        }
    }

    var myStructExistingValue = myStruct(programmeType: "Animation")
    var myStructNewValue = myStructExistingValue
    myStructNewValue.programmeType = "Thriller"

    print("myStructExistingValue: ", myStructExistingValue.programmeType)
    print("myStructNewValue: ", myStructNewValue.programmeType)

Keluaran:

Current Name:  John
Modified Name John
*************************
myStructExistingValue:  Animation
myStructNewValue:  Thriller
DILIP KOSURI
sumber
Hai Dilip, Dapatkah Anda memberikan contoh untuk "Struct aman thread atau singleton pada suatu titik waktu." ?. Terima kasih sebelumnya.
Narasimha Nallamsetty
3

Jika Anda melihat lebih jauh dalam buku pegangan apel Anda akan melihat bagian ini: "Struktur dan Penghitungan Adalah Jenis Nilai"

Di bagian ini Anda akan melihat ini:

“Biarkan hd = Resolusi (lebar: 1920, tinggi: 1080) var cinema = hd Contoh ini menyatakan konstanta yang disebut hd dan menetapkannya ke Resolusi Misalnya diinisialisasi dengan lebar dan tinggi video full HD (1920 piksel lebar 1080 piksel tinggi).

Ini kemudian mendeklarasikan variabel yang disebut bioskop dan set ke nilai hd saat ini. Karena Resolusi adalah struktur, salinan instance yang ada dibuat, dan salinan baru ini ditugaskan untuk bioskop. Meskipun hd dan bioskop sekarang memiliki lebar dan tinggi yang sama, mereka adalah dua contoh yang sangat berbeda di belakang layar.

Selanjutnya, properti lebar bioskop diubah menjadi lebar standar 2K yang sedikit lebih lebar yang digunakan untuk proyeksi bioskop digital (lebar 2048 piksel dan tinggi 1080 piksel):

Cinema. Width = 2048 Memeriksa lebar properti bioskop menunjukkan bahwa memang telah berubah menjadi 2048:

Println ("bioskop sekarang (bioskop. Lebar) piksel lebar") // cetak "bioskop sekarang lebarnya 2048 piksel Namun, properti lebarnya dari contoh hd asli masih memiliki yang lama nilai 1920:

println ("hd masih (lebar hd) lebar piksel") // mencetak "hd masih 1920 piksel lebar"

Ketika bioskop diberi nilai hd saat ini, nilai-nilai yang disimpan dalam hd disalin ke instance bioskop baru. Hasil akhirnya adalah dua contoh yang benar-benar terpisah, yang kebetulan mengandung nilai numerik yang sama. Karena mereka adalah instance yang terpisah, mengatur lebar bioskop ke 2048 tidak mempengaruhi lebar yang disimpan dalam hd. "

Kutipan dari: Apple Inc. “Bahasa Pemrograman Swift.” iBooks. https://itun.es/us/jEUH0.l

Ini adalah perbedaan terbesar antara struct dan kelas. Struct disalin dan kelas direferensikan.

Stuart Casarotto
sumber
1

Biasanya (dalam sebagian besar bahasa pemrograman), objek adalah blok data yang disimpan di heap, dan kemudian referensi (biasanya pointer) ke blok ini, berisi name yang digunakan untuk mengakses blok data ini. Mekanisme ini memungkinkan berbagi objek di heap dengan menyalin nilai referensi mereka (pointer). Ini bukan kasus tipe data dasar seperti Integer, dan itu karena memori yang diperlukan untuk membuat referensi hampir sama dengan objek (dalam hal ini nilai integer). Dengan demikian, mereka akan dilewatkan sebagai nilai bukan sebagai referensi dalam kasus objek besar.

Swift menggunakan struct untuk meningkatkan kinerja bahkan dengan objek String dan Array.

Bacaan yang sangat bagus di sini

William Kinaan
sumber
1

Untuk memahami perbedaan antara Structs dan Classes, kita perlu mengetahui perbedaan utama antara nilai dan tipe referensi. Structs adalah tipe nilai dan itu berarti bahwa setiap perubahan pada mereka hanya akan mengubah nilai itu, Kelas adalah tipe referensi dan setiap perubahan dalam tipe referensi akan mengubah nilai yang dialokasikan di tempat memori atau referensi itu. Sebagai contoh:

Mari kita mulai dengan Kelas, kelas ini sesuai dengan Equatable hanya untuk dapat membandingkan contoh, kita membuat instance yang dipanggil pointClassInstanceAdan lainnya yang disebut pointClassInstanceBkita menugaskan kelas A ke kelas B, sekarang pernyataan mengatakan bahwa mereka adalah sama ...

class PointClass: Equatable {
    var x: Double
    var y: Double

    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }

    static func == (lhs: PointClass, rhs: PointClass) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}

var pointClassInstanceA = PointClass(x: 0, y: 0)
var pointClassInstanceB = pointClassInstanceA

assert(pointClassInstanceA==pointClassInstanceB) 

pointClassInstanceB.x = 10
print(pointClassInstanceA.x)
//this prints 10

Ok, apa yang terjadi di sini mengapa jika kita hanya mengubah nilai x dari pointsClassInstanceB juga mengubah nilai x dari pointClassInstanceA? baik, ini menunjukkan bagaimana tipe referensi bekerja, ketika kita menetapkan instance A, sebagai nilai instance B dan kemudian kita memodifikasi X salah satunya, itu akan mengubah kedua X karena mereka berbagi referensi yang sama dan apa yang berubah adalah nilai dari itu referensi.

Mari kita lakukan hal yang sama tetapi dengan sebuah struct

struct PointStruct: Equatable {
    var x: Double
    var y: Double

    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }

    static func == (lhs: PointStruct, rhs: PointStruct) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}
var pointStructInstanceA = PointStruct(x: 0, y: 0)
var pointStructInstanceB = pointStructInstanceA

assert(pointStructInstanceA==pointStructInstanceB)
pointStructInstanceB.x = 100
print(pointStructInstanceA.x)
//this will print 0

Kami pada dasarnya memiliki struktur yang sama dengan kelas kami, tetapi sekarang Anda dapat melihat bahwa ketika Anda mencetak nilai x pointStructInstanceA hal ini tidak berubah, dan ini karena tipe nilai bekerja secara berbeda dan setiap perubahan pada salah satu instance mereka akan menjadi " independen "dan tidak akan mempengaruhi yang lain.

Swift menyarankan untuk menggunakan lebih banyak tipe nilai dan Anda dapat mengatakan bahwa pustaka mereka didasarkan pada struct untuk menghindari masalah yang dibawa oleh tipe referensi, seperti memodifikasi nilai secara tidak sengaja dll. Structs adalah cara untuk melanjutkan Swift. Semoga ini bisa membantu.

James Rochabrun
sumber
1

Berikut adalah contoh yang menunjukkan perbedaan antara struct dan kelas secara tepat.

tangkapan layar kode tertulis di taman bermain
tangkapan layar kode tertulis di taman bermain

struct Radio1{
    var name:String
    //    init(name:String) {
    //        self.name = name
    //    }
}

struct Car1{
    var radio:Radio1?
    var model:String

}

var i1 = Car1(radio: Radio1(name:"murphy"),model:"sedan")
var i2 = i1
//since car instance i1 is a struct and 
//this car has every member as struct ,
//all values are copied into i2

i2.radio?.name //murphy
i2.radio = Radio1(name: "alpha")
i2.radio?.name //alpha

i1.radio?.name //murphy

//since Radio1 was struct , 
//values were copied and thus
// changing name  of instance of Radio1 in i2 
//did not bring change in i1

class Radio2{
    var name:String
    init(name:String) {
        self.name = name
    }
}

struct Car2{
    var radio:Radio2?
    var model:String

}
var i3 = Car2(radio: Radio2(name:"murphy"),model:"sedan")
//var radioInstance = Radio2(name: "murphy")
//var i3 = Car2(radio: radioInstance,model:"sedan")

var i4 = i3
//since i3 is instance of struct
//everything is copied to i4 including reference of instance of Radio2
//because Radio2 is a class



i4.radio?.name //murphy
i4.radio?.name="alpha"
i4.radio?.name //alpha

i3.radio?.name //alpha

//since Radio2 was class, 
//reference was copied and 
//thus changing name of instance 
//of Radio2 in i4 did  bring change in i3 too


//i4.radio?.name
//i4.radio = Radio2(name: "alpha")
//i4.radio?.name
//
//i3.radio?.name
rahul verma
sumber
1
1.structure is value type.
   = > when we assign structure variable to other variable or pass as parameter to function, it creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by value** concept] 
Example :

    struct DemoStruct 
    { 
        var value: String 
        init(inValue: String) 
        { 
            self.value = inValue 
        } 
    } 


var aStruct = DemoStruct(inValue: "original") 
var bStruct = aStruct // aStruct and bStruct are two structs with the same value! but references to diff location`enter code here`
bStruct.value = "modified" 

print(aStruct.value) // "original" 
print(bStruct.value) // "modified"


2.class is reference type.
 = > when we assign structure variable to other variable or pass as parameter to function, it **does not** creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by reference** concept] 
Example:
class DemoClass 
{   
    var value: String 
    init(inValue: String) 
    {
        self.value = inValue 
    } 
} 

var aClass = DemoClass(inName: "original") 
var bClass = aClass // aClass and bClass now reference the same instance! 
bClass.value = "modified" 

print(aClass.value) // "modified" 
print(bClass.value) // "modified"
Sudhir Bhagat
sumber
1

Tipe cepat

Value type adalah tipe yang nilainya disalin ketika ditugaskan ke variabel atau konstan, atau ketika diteruskan ke suatu fungsi

Reference types tidak disalin ketika mereka ditugaskan ke variabel atau konstan, atau ketika mereka diteruskan ke suatu fungsi

Nilai Type :
Struct, Enum, Tuple
struct String, struct Array( Set, Dictionary)

  • Ketika Anda menetapkan atau lulus value type baru copy data dibuat. Sebenarnya copy on write- COWmekanisme digunakan dengan beberapa optimisasi, misalnya salinan dibuat ketika objek diubah
  • Ketika Anda memodifikasi sebuah instance, itu hanya memiliki efek lokal .
  • The Stack Memory digunakan.

Referensi Type :
Class,Function

  • Ketika Anda menetapkan atau lulus reference typesebuah referensi baru untuk contoh asli akan dibuat (alamat misalnya disalin).
  • Ketika Anda memodifikasi sebuah instance, ia memiliki efek global karena instance tersebut dibagikan dan dapat diakses oleh referensi apa pun yang menunjukkannya.
  • The Heap Memory digunakan.

masukkan deskripsi gambar di sini

Value typedisarankan untuk digunakan secara default . Keuntungan terbesar Value typeadalah biasanya merekathread safe

Reference type Pro:

  • mereka dapat diwarisi,
  • deinit() dapat digunakan,
  • bandingkan contoh dengan referensi ===,
  • Objective-Cinteroperabilitas karena Value Typediperkenalkan di Swift.

[Lebih lanjut tentang Mutabilitas]
Memilih Antara Struktur dan Kelas
Tipe
Kelas dan Struktur

yoAlex5
sumber
0

Alreday ada banyak yang ditulis tentang ini, saya ingin menambahkan analogi di sana. Harap Anda tidak akan pernah memiliki keraguan dalam pikiran setelah ini: Intinya: kelas dilewati oleh referensi sedangkan struct dilewatkan oleh nilai.

Misalkan Anda berbagi lembar google doc dengan teman Anda. Sekarang jika dia mengubah apa pun di dalamnya, Anda juga akan melihat bahwa perubahan di google doc Anda, berarti salinan Anda juga terpengaruh. Itu pada dasarnya " disahkan oleh referensi ".

Tapi anggaplah, jika Anda memiliki .XLS fie disimpan di mesin Anda. Anda memberikan file itu kepada teman Anda. Sekarang jika dia membuat perubahan pada file itu, file Anda tidak akan kacau / terpengaruh karena Anda memiliki salinan Anda sendiri. Itu pada dasarnya " dilewati oleh nilai ". Anda memiliki beberapa program sederhana yang sudah ada di sana untuk memeriksa analogi ini di taman bermain cepat.

ASP
sumber