language - swift tutorial




দ্রুত বর্গ মধ্যে গঠন বনাম ক্লাস (8)

Alreday এই সম্পর্কে অনেক লেখা আছে, আমি সেখানে একটি উপমা যোগ করতে চাই। আপনি এই পরে মনের সন্দেহ কখনও হবে আশা করি: নিচের লাইন: ক্লাস উল্লেখ দ্বারা পাস করা হয়, যখন structs মান দ্বারা পাস করা হয়।

ধরুন আপনি আপনার বন্ধুর সাথে একটি গুগল ডক শীট শেয়ার করছেন। এখন সে যদি কিছু পরিবর্তন করে তবে আপনি আপনার গুগল ডক এর পরিবর্তনগুলি দেখতে পাবেন, যার মানে আপনার কপিটিও প্রভাবিত। যে মূলত " রেফারেন্স দ্বারা পাস "।

কিন্তু ধরুন, আপনার যদি কোনও .XLS fie আপনার মেশিনে সংরক্ষিত থাকে। আপনি যে ফাইল আপনার বন্ধু দিতে প্রদান। এখন সে যে ফাইলটিতে কোনও পরিবর্তন করছে, আপনার ফাইলটি আপত্তিজনক / প্রভাবিত হবে না কারণ আপনার নিজস্ব কপি রয়েছে। যে মূলত " মান দ্বারা পাস "। তাত্ক্ষণিক playgrounds মধ্যে এই উপমা চেক করার জন্য ইতিমধ্যে আপনি একাধিক সহজ প্রোগ্রাম আছে।

অ্যাপল বই থেকে "কাঠামো এবং ক্লাসের মধ্যে সবচেয়ে গুরুত্বপূর্ণ পার্থক্যগুলির মধ্যে একটি হল যে আপনার কোডগুলিতে প্রায় পাস করার সময় কাঠামোগুলি সর্বদা অনুলিপি করা হয় তবে ক্লাস রেফারেন্স দ্বারা পাস করা হয়।"

যে কেউ আমাকে বোঝাতে দেয় কি মানে, আমার জন্য ক্লাস এবং কাঠামো একই বলে মনে হয়।


উপরোক্ত উত্তরগুলি সঠিক, আমি আশা করি আমার উত্তর এমন কেউকে সাহায্য করবে যিনি উত্তরের উত্তরগুলি বুঝতে পারছেন না।

ওয়েল সুইফ্টে দুটি ধরনের বস্তু রয়েছে

  1. struct
  2. শ্রেণী

তাদের মধ্যে প্রধান পার্থক্য হয়

  • গঠন মান টাইপ
  • ক্লাস রেফারেন্স টাইপ

উদাহরণস্বরূপ এখানে কোড ভাল বুঝতে।

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

এটি মূল পার্থক্য ছিল কিন্তু আমাদের উপ-পার্থক্য রয়েছে।

শ্রেণী

  1. প্রাথমিকীকরণকারী (নির্মাতা) ঘোষণা করা আবশ্যক
  2. Deinitialisers আছে
  3. অন্যান্য ক্লাস থেকে উত্তরাধিকারী করতে পারেন

struct

  1. এটি আপনার জন্য বিনামূল্যে প্রারম্ভিক আছে, যদি আপনি বিনামূল্যে ঘোষক আপনার ঘোষিত initialiser দ্বারা overwritten করা হবে না ifitaliser ঘোষণা করতে হবে না
  2. Deinitialiser আছে না
  3. অন্যান্য struct থেকে উত্তরাধিকারী করতে পারবেন না

এই প্রশ্নটি সদৃশ বলে মনে হচ্ছে তবে নির্বিশেষে, নিম্নলিখিত ক্ষেত্রে বেশীরভাগ ক্ষেত্রেই উত্তর দেওয়া হবে:

  1. কাঠামো এবং ক্লাসগুলির মধ্যে সবচেয়ে গুরুত্বপূর্ণ পার্থক্য হল কাঠামোগুলি মানের ধরন এবং আপনার কোডে প্রায় পাস করার সময় সর্বদা অনুলিপি করা হয় এবং ক্লাস রেফারেন্সের ধরন এবং রেফারেন্স দ্বারা গৃহীত হয়।

  2. এছাড়াও, ক্লাসের উত্তরাধিকার রয়েছে যা এক শ্রেণীরকে অন্য বৈশিষ্ট্যগুলির উত্তরাধিকারী করে।

  3. স্ট্যাক এবং ক্লাসের উদাহরণগুলিতে স্ট্রাকচারের বৈশিষ্ট্যগুলি হিপে সংরক্ষণ করা হয়, তাই কখনও কখনও স্ট্যাকটি ক্লাসের চেয়ে দ্রুততর হয়।

  4. স্ট্রাকটি স্বয়ংক্রিয়ভাবে ডিফল্ট প্রারম্ভিক প্রযোজক পায় তবে ক্লাসে, আমাদেরকে প্রাথমিকভাবে শুরু করতে হয়।

  5. কাঠামো থ্রেড নিরাপদ বা কোনো সময়ে সময়ে এককোন।

এবং এছাড়াও, structs এবং ক্লাসের মধ্যে পার্থক্য সংক্ষিপ্তসার করতে, মূল্য এবং রেফারেন্সের ধরনগুলির মধ্যে পার্থক্যটি বোঝা প্রয়োজন।

  1. যখন আপনি একটি মান টাইপের একটি অনুলিপি তৈরি করেন, তখন এটি নতুন ডাটাতে অনুলিপি করা সমস্ত তথ্যকে কপি করে। তারা 2 পৃথক জিনিস এবং পরিবর্তন এক অন্য প্রভাবিত করে না।
  2. যখন আপনি একটি রেফারেন্স টাইপের অনুলিপি তৈরি করেন, তখন নতুন পরিবর্তনশীলটি একই মেমরির অবস্থানকে বোঝায় যা আপনি অনুলিপি করছেন। এর অর্থ এই যে, উভয়ই একই মেমরির অবস্থানটি উল্লেখ করে অন্যটি পরিবর্তন করবে। নীচের নমুনা কোড রেফারেন্স হিসাবে গ্রহণ করা যেতে পারে।

// নমুনা খেলার মাঠ

  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)

আউটপুট:

Current Name:  John
Modified Name John
*************************
myStructExistingValue:  Animation
myStructNewValue:  Thriller

এখানে একটি class সঙ্গে একটি উদাহরণ। উল্লেখ্য কিভাবে নাম পরিবর্তিত হয়, উভয় ভেরিয়েবলের দ্বারা উল্লিখিত উদাহরণ আপডেট করা হয়। Bob এখন Sue , সর্বত্র যে Bob কখনও রেফারেন্স ছিল।

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"

এবং এখন একটি struct আমরা দেখি যে মানগুলি অনুলিপি করা হয়েছে এবং প্রতিটি পরিবর্তনশীল এটির মানগুলির নিজস্ব সেট রাখে। যখন আমরা Sue নাম সেট করি, তখন aStruct Bob aStruct পরিবর্তন হয় না।

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"

সুতরাং একটি রাষ্ট্রীয় জটিল সত্তা প্রতিনিধিত্ব করার জন্য, একটি class অসাধারণ। কিন্তু মানগুলির জন্য কেবলমাত্র একটি পরিমাপ বা সম্পর্কিত তথ্যগুলির বিট, একটি struct আরো জ্ঞান দেয় যাতে আপনি সহজে তাদের কাছাকাছি অনুলিপি করতে পারেন এবং তাদের সাথে গণনা করতে পারেন বা পার্শ্ব প্রতিক্রিয়াগুলির ভয় ছাড়াই মানগুলি সংশোধন করতে পারেন।


কাঠামো এবং শ্রেণীগুলির মধ্যে পার্থক্য বোঝার জন্য, আমাদের মূল্য এবং রেফারেন্সের ধরনগুলির মধ্যে প্রধান পার্থক্য জানতে হবে। স্ট্রাক্টগুলি মানের ধরন এবং এর মানে হল যে তাদের প্রতিটি পরিবর্তন কেবল সেই মানটি সংশোধন করবে, ক্লাস রেফারেন্সের ধরন এবং রেফারেন্স টাইপের প্রতিটি পরিবর্তন মেমরি বা রেফারেন্সের বরাদ্দ করা মানটিকে সংশোধন করবে। উদাহরণ স্বরূপ:

আসুন ক্লাসের সাথে শুরু করি, এই শ্রেণীটি দৃষ্টান্তের সাথে তুলনা করার জন্য সমতুল্য রূপ ধারণ করে, আমরা pointClassInstanceA নামক একটি উদাহরণ তৈরি pointClassInstanceA এবং অন্যটি বলা হয় pointClassInstanceB আমরা ক্লাস A কে বর্গ বি বরাদ্দ করি, এখন pointClassInstanceB কথা তারা বলে যে ...

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

আচ্ছা, এখানে কী ঘটেছে কেন আমরা যদি পয়েন্ট ক্ল্যাসইনস্ট্যান্স বি এর x মান পরিবর্তন করেছিলাম তবে এটি pointClassInstanceA এর x মান পরিবর্তন করেছিল? ভাল, এটি দেখায় কিভাবে রেফারেন্স টাইপ কাজ করে, যখন আমরা ইনস্ট্যান্স A কে একটি উদাহরণ B এর মান হিসাবে বরাদ্দ করি এবং তারপর আমরা তাদের মধ্যে একটি এক্স সংশোধন করি তবে এটি এক্স উভয়কে পরিবর্তন করবে কারণ এটি একই রেফারেন্স ভাগ করে এবং এর মান কী পরিবর্তিত হয়েছে রেফারেন্স।

আসুন একটি 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

আমরা মূলত আমাদের শ্রেণী হিসাবে একই কাঠামো আছে কিন্তু এখন আপনি দেখতে পারেন যে যখন আপনি পয়েন্ট স্ট্রাকচারইনস্টেন্সএর x মানটি মুদ্রণ করেন তখন এই ক্ষেত্রে এটি পরিবর্তন হয় নি এবং মান কারণগুলি ভিন্নভাবে কাজ করে এবং তাদের একটি উদাহরণে প্রতিটি পরিবর্তন " স্বাধীন "এবং অন্য প্রভাবিত করবে না।

সুইফ্ট আরো মূল্যের ধরনগুলি ব্যবহার করার পরামর্শ দেয় এবং আপনি বলতে পারেন যে তাদের লাইব্রেরিগুলি স্ট্রাক্টগুলির উপর ভিত্তি করে যা ধরণের প্রসঙ্গগুলি আনতে সমস্যাগুলি এড়ানোর জন্য, যেমন অচেনাভাবে একটি মান সংশোধন ইত্যাদি ইত্যাদি এড়িয়ে চলতে পারে। স্ট্রিপ্টগুলি সুইফ্টে যাওয়ার উপায়। আশা করি এটা সাহায্য করবে.


যদি আপনি আপেল হ্যান্ডবুকে আরও বেশি দেখেন তবে আপনি এই বিভাগটি দেখতে পাবেন: "কাঠামো এবং পরিসংখ্যান মানের ধরন"

এই বিভাগে আপনি এটি দেখতে পাবেন:

"এইচডি = রেজোলিউশন (প্রস্থ: 1920, উচ্চতা: 1080) var সিনেমা = এইচডি এই উদাহরণটি হ্যালো বলা একটি ধ্রুবক ঘোষণা করে এবং এটি একটি রেজোলিউশনে সেট করে উদাহরণটি পূর্ণ এইচডি ভিডিওর প্রস্থ এবং উচ্চতার সাথে প্রারম্ভিক (1920 পিক্সেলের উচ্চতা 1080 পিক্সেল উচ্চ) দিয়ে শুরু হয়েছে।

এটি তখন সিনেমা নামে একটি পরিবর্তনশীল ঘোষণা করে এবং এটি HD এর বর্তমান মানতে সেট করে। কারণ রেজোলিউশনটি একটি কাঠামো, বিদ্যমান ইনস্ট্যান্সের একটি অনুলিপি তৈরি করা হয় এবং এই নতুন অনুলিপিটিকে সিনেমায় বরাদ্দ করা হয়। যদিও এইচডি এবং সিনেমার এখন একই প্রস্থ এবং উচ্চতা রয়েছে, তবে দৃশ্যগুলির পিছনে দুটি সম্পূর্ণ ভিন্ন দৃষ্টান্ত রয়েছে।

পরবর্তীতে, ডিজিটাল সিনেমা অভিক্ষেপ (2048 পিক্সেল প্রশস্ত এবং 1080 পিক্সেল উচ্চ) জন্য ব্যবহৃত সামান্য-বৃহত্তর 2K মানের প্রস্থ হতে চলচ্চিত্রের প্রস্থ সম্পত্তি সংশোধন করা হয়েছে:

সিনেমা। প্রস্থ = 2048 সিনেমাটির প্রস্থ সম্পত্তি পরীক্ষা করে দেখায় যে এটি প্রকৃতপক্ষে 2048 হতে পরিবর্তিত হয়েছে:

Println ("সিনেমা এখন (সিনেমা। প্রস্থ) পিক্সেল প্রশস্ত") // প্রিন্ট "সিনেমা এখন 2048 পিক্সেল প্রশস্ত। তবে, মূল HD ইনস্ট্যান্সের প্রস্থ সম্পত্তি এখনও পুরানো আছে 1920 এর মান:

println ("এইচডি এখনও (এইচডি। প্রস্থ) পিক্সেল প্রশস্ত") // প্রিন্টগুলি "এইচডি এখনও 1920 পিক্সেল প্রশস্ত"

যখন সিনেমাটিকে HD এর বর্তমান মান দেওয়া হয়, তখন HD তে সংরক্ষিত মানগুলি নতুন সিনেমা দৃষ্টান্তে অনুলিপি করা হয়। শেষ ফলাফল দুটি সম্পূর্ণ আলাদা উদাহরণ, যা ঠিক একই সাংখ্যিক মান ধারণ ঘটেছে। কারণ তারা আলাদা দৃষ্টান্ত, 2048 এ সিনেমাটির প্রস্থ নির্ধারণ করা HD তে সংরক্ষিত প্রস্থকে প্রভাবিত করে না। "

থেকে উদ্ধৃতি: অ্যাপল ইনক। "সুইফ্ট প্রোগ্রামিং ভাষা।" আইবুক। https://itun.es/us/jEUH0.l

এই structs এবং ক্লাসের মধ্যে বৃহত্তম পার্থক্য। রেখাচিত্র অনুলিপি করা হয় এবং ক্লাস রেফারেন্স করা হয়।


struct মান ধরনের হয়। এর মানে হল যে যদি আপনি অন্য পরিবর্তনশীল রূপে গঠনটির উদাহরণটি অনুলিপি করেন তবে এটি কেবল পরিবর্তনশীলকে অনুলিপি করা হয়।

মান টাইপ জন্য উদাহরণ

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

ক্লাস রেফারেন্স ধরনের হয়। এর মানে হল যে আপনি যদি কোন পরিবর্তনশীলকে ক্লাসের একটি উদাহরণ বরাদ্দ করেন তবে এটি কেবল উদাহরণের রেফারেন্স ধারণ করবে এবং অনুলিপি নয়


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"






swift