জাভা ব্যাকগ্রাউন্ড থেকে আসা সুইফ্টের সাথে ঘুরে বেড়ানো, আপনি কেন ক্লাসের পরিবর্তে স্ট্রাক্ট বেছে নিতে চান? স্ট্রাক্ট কম কার্যকারিতা সরবরাহ করে এমন তারা একই জিনিস বলে মনে হয়। তাহলে কেন এটি বেছে নিন?
জাভা ব্যাকগ্রাউন্ড থেকে আসা সুইফ্টের সাথে ঘুরে বেড়ানো, আপনি কেন ক্লাসের পরিবর্তে স্ট্রাক্ট বেছে নিতে চান? স্ট্রাক্ট কম কার্যকারিতা সরবরাহ করে এমন তারা একই জিনিস বলে মনে হয়। তাহলে কেন এটি বেছে নিন?
উত্তর:
অত্যন্ত জনপ্রিয় ডাব্লুডাব্লুডিসি 2015 টক প্রোটোকল ওরিয়েন্টেড প্রোগ্রামিং ইন সুইফট ( ভিডিও , প্রতিলিপি ) অনুসারে, সুইফট এমন অনেকগুলি বৈশিষ্ট্য সরবরাহ করে যা বিভিন্ন পরিস্থিতিতে ক্লাসের চেয়ে স্ট্রাক্টকে আরও ভাল করে তোলে।
স্ট্রাক্টগুলি তুলনামূলকভাবে ছোট এবং অনুলিপিযোগ্য হওয়াকেই বেশি পছন্দনীয় কারণ অনুলিপি ক্লাসগুলির সাথে ঘটে যাওয়া একই উদাহরণের একাধিক উল্লেখ থাকার চেয়ে নিরাপদ। এটি বিশেষত গুরুত্বপূর্ণ যখন অনেকগুলি ক্লাসে এবং / অথবা একটি বহুবিবাহিত পরিবেশে ভেরিয়েবলের পাশ দিয়ে যায়। আপনি যদি সর্বদা আপনার পরিবর্তকের একটি অনুলিপি অন্য জায়গায় প্রেরণ করতে পারেন তবে আপনাকে অন্য স্থানের নীচে আপনার ভেরিয়েবলের মান পরিবর্তন করার বিষয়ে চিন্তা করতে হবে না।
স্ট্রাক্টসের সাহায্যে ভেরিয়েবলের একক উদাহরণ অ্যাক্সেস / সংশোধন করতে মেমরি ফাঁস বা একাধিক থ্রেড রেসিংয়ের বিষয়ে চিন্তা করার খুব কম দরকার। (আরও প্রযুক্তিগত বিবেচনার জন্য, ব্যতিক্রমটি হ'ল বন্ধের অভ্যন্তরে কোনও কাঠামো ক্যাপচার করার সময় কারণ এটি প্রকৃতপক্ষে কোনও রেফারেন্স ক্যাপচার করছে যদি আপনি এটি স্পষ্টভাবে অনুলিপি না করে চিহ্নিত করেন)।
শ্রেণিগুলিও বিকাশিত হতে পারে কারণ একটি শ্রেণি কেবলমাত্র একটিমাত্র সুপারক্লাস থেকে উত্তরাধিকারী হতে পারে। এটি আমাদেরকে এমন বিশাল সুপারক্লাস তৈরি করতে উত্সাহিত করে যা কেবলমাত্র আলগাভাবে সম্পর্কিত অনেকগুলি বিভিন্ন দক্ষতা পরিবেষ্টিত করে। প্রোটোকল ব্যবহার করে, বিশেষত প্রোটোকল এক্সটেনশনগুলির সাথে যেখানে আপনি প্রোটোকলগুলিতে বাস্তবায়ন সরবরাহ করতে পারেন, আপনাকে এই ধরণের আচরণ অর্জনের জন্য ক্লাসগুলির প্রয়োজনীয়তা অপসারণ করতে দেয়।
আলোচনায় এই পরিস্থিতিগুলি পেশ করা হয় যেখানে ক্লাসগুলি অগ্রাধিকার দেওয়া হয়:
- দৃষ্টান্তগুলি অনুলিপি করা বা তুলনা করা অর্থপূর্ণ নয় (উদাঃ উইন্ডো)
- উদাহরণ জীবনকাল বাহ্যিক প্রভাবের সাথে আবদ্ধ (যেমন টেম্পোরারি ফাইল)
- উদাহরণগুলি কেবল "ডুব" - কেবলমাত্র বাহ্যিক অবস্থানে লেখার জন্য পাঠ্যক্রম (যেমন সি.সি.জি. কনটেক্সট)
এটি সূচিত করে যে স্ট্রাক্টগুলি ডিফল্ট হওয়া উচিত এবং ক্লাসগুলি ফ্যালব্যাক হওয়া উচিত।
অন্যদিকে, দ্য সুইফ্ট প্রোগ্রামিং ল্যাঙ্গুয়েজ ডকুমেন্টেশন কিছুটা বিপরীত:
কাঠামোর দৃষ্টান্তগুলি সর্বদা মান দ্বারা পাস হয় এবং শ্রেণীর দৃষ্টান্ত সর্বদা রেফারেন্স দ্বারা প্রেরণ করা হয়। এর অর্থ হল যে তারা বিভিন্ন ধরণের কাজে উপযুক্ত suited আপনি যেমন কোনও প্রকল্পের জন্য প্রয়োজনীয় ডেটা গঠন এবং কার্যকারিতা বিবেচনা করেন, তেমনি সিদ্ধান্ত নিন যে প্রতিটি ডেটা কনস্ট্রাক্টকে শ্রেণি বা কাঠামো হিসাবে সংজ্ঞায়িত করা উচিত।
সাধারণ নির্দেশিকা হিসাবে, যখন এই শর্তগুলির মধ্যে এক বা একাধিক প্রয়োগ হয় তখন একটি কাঠামো তৈরির কথা বিবেচনা করুন:
- কাঠামোর প্রাথমিক উদ্দেশ্যটি কয়েকটি অপেক্ষাকৃত সাধারণ ডেটা মানকে সজ্জিত করা।
- আপনি যখন কাঠামোর কোনও উদাহরণ বরাদ্দ করেন বা পাস করেন তখন এনক্যাপসুলেটেড মানগুলি অনুলিপি করা হবে না তা আশা করা যুক্তিসঙ্গত।
- কাঠামোর দ্বারা সঞ্চিত যে কোনও সম্পত্তি হ'ল তারা মান ধরণের, যা রেফারেন্সের চেয়ে অনুলিপি করাও আশা করা যায়।
- কাঠামোর জন্য অন্য বিদ্যমান ধরণের বৈশিষ্ট্য বা আচরণের উত্তরাধিকারের প্রয়োজন নেই।
কাঠামোর জন্য ভাল প্রার্থীদের উদাহরণগুলির মধ্যে রয়েছে:
- জ্যামিতিক আকারের আকার, সম্ভবত একটি প্রস্থের সম্পত্তি এবং একটি উচ্চতার সম্পত্তি, ডাবল উভয় প্রকারকে আবদ্ধ করে।
- একটি সিরিজের মধ্যে ব্যাপ্তি উল্লেখ করার উপায়, সম্ভবত প্রারম্ভিক সম্পত্তি এবং দৈর্ঘ্যের সম্পত্তি, উভয় প্রকারের অন্তর্ভুক্ত করে enc
- একটি 3D স্থানাঙ্ক ব্যবস্থার একটি বিন্দু, সম্ভবত x, y এবং z বৈশিষ্ট্যগুলি এনক্যাপসুলেট করে প্রতিটি ডাবল টাইপ করে।
অন্যান্য সমস্ত ক্ষেত্রে, একটি শ্রেণি সংজ্ঞায়িত করুন, এবং সেই শ্রেণীর উদাহরণ এবং ব্যবস্থাপনার মাধ্যমে রেফারেন্স দ্বারা পাস করার উদাহরণ তৈরি করুন। অনুশীলনে, এর অর্থ হ'ল বেশিরভাগ কাস্টম ডেটা কনস্ট্রাক্টস কাঠামো নয়, ক্লাস হওয়া উচিত।
এখানে এটি দাবি করা হচ্ছে যে কেবলমাত্র নির্দিষ্ট পরিস্থিতিতে ক্লাস ব্যবহার এবং কাঠামোগত ব্যবহারের ক্ষেত্রে আমাদের ডিফল্ট হওয়া উচিত। শেষ অবধি, আপনাকে মূল্য প্রকারের বনাম রেফারেন্স প্রকারের প্রকৃত বিশ্বজগত বুঝতে হবে এবং তারপরে আপনি কখন স্ট্রাক্ট বা ক্লাস ব্যবহার করবেন সে সম্পর্কে একটি অবগত সিদ্ধান্ত নিতে পারেন। এছাড়াও, মনে রাখবেন যে এই ধারণাগুলি সর্বদা বিকশিত হয় এবং প্রোটোকল ওরিয়েন্টেড প্রোগ্রামিং টক দেওয়ার আগে সুইফ্ট প্রোগ্রামিং ল্যাঙ্গুয়েজ ডকুমেন্টেশন লেখা হয়েছিল।
In practice, this means that most custom data constructs should be classes, not structures.
আপনি কী আমাকে ব্যাখ্যা করতে পারেন যে এটি পড়ার পরে আপনি কীভাবে সর্বাধিক ডেটা সেটগুলি কাঠামোযুক্ত হওয়া উচিত এবং ক্লাস নয়? তারা কোনও নির্দিষ্ট নিয়মের একটি সেট দেয় যখন কোনও কিছু কাঠামোযুক্ত হওয়া উচিত এবং বেশ কিছুটা বলা উচিত "অন্য শ্রেণীর সমস্ত পরিস্থিতি একটি শ্রেণীর চেয়ে ভাল।"
যেহেতু স্ট্রাক্টের জন্য স্ট্রাক্ট উদাহরণগুলি বরাদ্দ করা হয়, এবং শ্রেণীর দৃষ্টান্তগুলি স্তূপে বরাদ্দ করা হয়, স্ট্রাক্টগুলি মাঝে মাঝে মারাত্মকভাবে দ্রুততর হতে পারে।
যাইহোক, আপনার সর্বদা এটি নিজেই পরিমাপ করা উচিত এবং আপনার অনন্য ব্যবহারের ক্ষেত্রে ভিত্তিতে সিদ্ধান্ত নেওয়া উচিত।
নিম্নলিখিত উদাহরণটি বিবেচনা করুন, যা এবং Int
ব্যবহার করে ডেটা টাইপ মোড়ানোর 2 কৌশল প্রদর্শন করে । আমি 10 টি পুনরাবৃত্ত মানগুলি ব্যবহার করছি সত্যিকারের বিশ্বকে আরও ভালভাবে প্রতিবিম্বিত করতে, যেখানে আপনার একাধিক ক্ষেত্র রয়েছে।struct
class
class Int10Class {
let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int
init(_ val: Int) {
self.value1 = val
self.value2 = val
self.value3 = val
self.value4 = val
self.value5 = val
self.value6 = val
self.value7 = val
self.value8 = val
self.value9 = val
self.value10 = val
}
}
struct Int10Struct {
let value1, value2, value3, value4, value5, value6, value7, value8, value9, value10: Int
init(_ val: Int) {
self.value1 = val
self.value2 = val
self.value3 = val
self.value4 = val
self.value5 = val
self.value6 = val
self.value7 = val
self.value8 = val
self.value9 = val
self.value10 = val
}
}
func + (x: Int10Class, y: Int10Class) -> Int10Class {
return IntClass(x.value + y.value)
}
func + (x: Int10Struct, y: Int10Struct) -> Int10Struct {
return IntStruct(x.value + y.value)
}
পারফরম্যান্স ব্যবহার করে পরিমাপ করা হয়
// Measure Int10Class
measure("class (10 fields)") {
var x = Int10Class(0)
for _ in 1...10000000 {
x = x + Int10Class(1)
}
}
// Measure Int10Struct
measure("struct (10 fields)") {
var y = Int10Struct(0)
for _ in 1...10000000 {
y = y + Int10Struct(1)
}
}
func measure(name: String, @noescape block: () -> ()) {
let t0 = CACurrentMediaTime()
block()
let dt = CACurrentMediaTime() - t0
print("\(name) -> \(dt)")
}
কোডটি https://github.com/knguyen2708/StructVsClassPerformance এ পাওয়া যাবে
আপডেট (27 মার্চ 2018) :
আইফোন 6 এস, আইওএস 11.2.6 এ রিলিজ বিল্ড চলমান সুইফট ৪.০, এক্সকোড ৯.২, সুইফট সংকলক সেটিংটি হ'ল -O -whole-module-optimization
:
class
সংস্করণটি 2.06 সেকেন্ড সময় নিয়েছেstruct
সংস্করণটি 4.17e-08 সেকেন্ড সময় নিয়েছে (50,000,000 বার দ্রুত)(আমি আর একাধিক রান গড় করি না, কারণ রূপগুলি খুব কম, 5% এর নীচে থাকে)
দ্রষ্টব্য : সম্পূর্ণ মডিউল অপ্টিমাইজেশন ছাড়াই পার্থক্যটি অনেক কম নাটকীয়। কেউ যদি পতাকাটি আসলে কী করে তা নির্দেশ করতে পারে তবে আমি খুশি হব।
আপডেট (7 মে 2016) :
সুইফট ২.২.১, এক্সকোড .3.৩, আইফোন S এস, আইওএস 9.৩.১-তে চলমান রিলিজ বিল্ড, গড়ে পাঁচ রানেরও বেশি, সুইফট সংকলক সেটিংটি হ'ল -O -whole-module-optimization
:
class
সংস্করণটি 2.159942142 সেকেন্ডে নিয়েছেstruct
সংস্করণটি 5.83E-08 সেকেন্ডে নিয়েছে (37,000,000 বার দ্রুত)দ্রষ্টব্য : যেহেতু কেউ উল্লেখ করেছেন যে বাস্তব-জগতের পরিস্থিতিতে, কোনও কাঠামোতে সম্ভবত 1 টিরও বেশি ক্ষেত্র থাকবে, আমি স্ট্রাক্ট / ক্লাসের জন্য 10 টি ক্ষেত্রের সাথে পরীক্ষার যোগ করেছি 1 টির পরিবর্তে 10 টি ক্ষেত্র Sur
মূল ফলাফল (1 জুন 2014):
(10 টি নয়, 1 টি ক্ষেত্র সহ স্ট্রাক্ট / ক্লাসে দৌড়ে)
আইফোন 5 এস, আইওএস 8.3 এ রিলিজ বিল্ড চলমান সুইফট 1.2, এক্সকোড 6.3.2 হিসাবে, গড়ে 5 রান
class
সংস্করণটি 9.788332333s নিয়েছেstruct
সংস্করণটি 0.010532942s (900 গুণ দ্রুত) নিয়েছেপুরানো ফলাফল (অজানা সময় থেকে)
(10 টি নয়, 1 টি ক্ষেত্র সহ স্ট্রাক্ট / ক্লাসে দৌড়ে)
আমার ম্যাকবুক প্রোতে মুক্তির সাথে:
class
সংস্করণ 1,10082 সেকেন্ড নেনstruct
সংস্করণ 0,02324 সেকেন্ড নেন (50 গুণ দ্রুত)আমি সহজ উদাহরণ দিয়ে এর জন্য সংক্ষেপ তৈরি করেছি created https://github.com/objc-swift/swift-classes-vs-structures
কাঠামোগুলি দ্রুতগতিতে উত্তরাধিকারী হতে পারে না। তুমি যদি চাও
class Vehicle{
}
class Car : Vehicle{
}
একটি ক্লাস জন্য যান।
সুইফ্ট স্ট্রাকচারগুলি মান দ্বারা পাস হয় এবং শ্রেণীর দৃষ্টান্তগুলি রেফারেন্স দ্বারা পাস হয়।
ধ্রুবক এবং ভেরিয়েবলগুলি গঠন করুন
উদাহরণ (ডাব্লুডাব্লুডিসি 2014 এ ব্যবহৃত)
struct Point{
var x = 0.0;
var y = 0.0;
}
পয়েন্ট নামক একটি কাঠামো সংজ্ঞায়িত করে।
var point = Point(x:0.0,y:2.0)
এখন আমি এক্স পরিবর্তন করার চেষ্টা করি। এটি একটি বৈধ অভিব্যক্তি।
point.x = 5
তবে যদি আমি কোনও বিন্দুকে ধ্রুবক হিসাবে সংজ্ঞায়িত করি।
let point = Point(x:0.0,y:2.0)
point.x = 5 //This will give compile time error.
এই ক্ষেত্রে পুরো পয়েন্ট অপরিবর্তনীয় ধ্রুবক।
পরিবর্তে আমি যদি কোনও ক্লাস পয়েন্ট ব্যবহার করি তবে এটি একটি বৈধ এক্সপ্রেশন। কারণ একটি শ্রেণিতে অপরিবর্তনীয় ধ্রুবক হল শ্রেণীর সাথে তার উল্লেখ ভেরিয়েবলগুলি উল্লেখ করা হয় না (যদি না vari ভেরিয়েবলগুলি ধ্রুবক হিসাবে সংজ্ঞায়িত করা হয়)
এখানে বিবেচনা করার জন্য আরও কিছু কারণ রয়েছে:
স্ট্রাইকগুলি একটি স্বয়ংক্রিয় সূচনা প্রাপ্ত করে যা আপনাকে কোনও কোডে বজায় রাখতে হবে না।
struct MorphProperty {
var type : MorphPropertyValueType
var key : String
var value : AnyObject
enum MorphPropertyValueType {
case String, Int, Double
}
}
var m = MorphProperty(type: .Int, key: "what", value: "blah")
এটি একটি ক্লাসে পেতে, আপনাকে আরম্ভকারীটি যুক্ত করতে হবে, এবং অন্তর্নিবেশককে বজায় রাখতে হবে ...
বেসিক সংগ্রহের Array
ধরণগুলি যেমন স্ট্র্টস। এগুলি আপনি আপনার নিজের কোডগুলিতে যত বেশি ব্যবহার করবেন, আপনি রেফারেন্সের বিপরীতে মান দ্বারা পাস করার জন্য তত বেশি অভ্যস্ত হয়ে উঠবেন। এই ক্ষেত্রে:
func removeLast(var array:[String]) {
array.removeLast()
println(array) // [one, two]
}
var someArray = ["one", "two", "three"]
removeLast(someArray)
println(someArray) // [one, two, three]
স্পষ্টতই অপরিবর্তনীয়তা বনাম পরিবর্তনশীলতা একটি বিশাল বিষয়, তবে প্রচুর স্মার্ট লোকেরা অপরিবর্তনীয়তা - এই ক্ষেত্রে স্ট্রাক্টগুলি - পছন্দনীয়। পরিবর্তনীয় বনাম অপরিবর্তনীয় বস্তু
internal
সুযোগের জন্য উপলব্ধ হন তবে আপনাকে অবশ্যই প্রাথমিকভাবে নিজেকে লিখতে হবে ।
mutating
যাতে কোন ফাংশনগুলি তাদের স্থিতি পরিবর্তন করে সে সম্পর্কে আপনি স্পষ্ট। তবে মানের ধরণ হিসাবে তাদের প্রকৃতিটি গুরুত্বপূর্ণ। আপনি যদি let
এটির সাথে কোনও কাঠামো ঘোষণা করেন তবে আপনি এটিতে কোনও রূপান্তরকারী ফাংশন কল করতে পারবেন না। মান প্রকারের মাধ্যমে আরও ভাল প্রোগ্রামিংয়ের উপর ডাব্লুডাব্লুডিসি 15 ভিডিও এটির একটি দুর্দান্ত উত্স।
ধরে নিলাম যে আমরা জানি স্ট্রাক্ট একটি মান ধরণের এবং শ্রেণি একটি রেফারেন্স টাইপ ।
মান মান এবং রেফারেন্স টাইপ কী কী তা যদি আপনি না জানেন তবে দেখুন রেফারেন্স দ্বারা মান বনাম পাস করার মধ্যে পার্থক্য কী?
মিকাশের পোস্টের ভিত্তিতে :
... প্রথমে কিছু চরম, সুস্পষ্ট উদাহরণ দেখি। পূর্ণসংখ্যা স্পষ্টতই অনুলিপিযোগ্য। এগুলি মান ধরণের হওয়া উচিত। নেটওয়ার্ক সকেটগুলি সংবেদনশীলভাবে অনুলিপি করা যায় না। সেগুলি রেফারেন্স ধরণের হওয়া উচিত। X, y জোড়া হিসাবে পয়েন্টগুলি অনুলিপিযোগ্য। এগুলি মান ধরণের হওয়া উচিত। কোনও নিয়ামক যা ডিস্ককে উপস্থাপন করে সংবেদনশীলভাবে অনুলিপি করা যায় না। এটি একটি রেফারেন্স টাইপ হওয়া উচিত।
কিছু প্রকারের অনুলিপি করা যায় তবে এটি এমন কিছু নাও হতে পারে যা আপনি সর্বদা ঘটতে চান। এটি পরামর্শ দেয় যে এগুলি রেফারেন্স ধরণের হওয়া উচিত। উদাহরণস্বরূপ, পর্দার একটি বোতাম ধারণামূলকভাবে অনুলিপি করা যেতে পারে। অনুলিপিটি মূলটির সাথে একরকম হবে না। অনুলিপিটিতে ক্লিক করলে মূলটি সক্রিয় হবে না। অনুলিপি পর্দায় একই অবস্থান দখল করবে না। আপনি যদি বোতামটি চারপাশে পাস করেন বা এটি একটি নতুন ভেরিয়েবলের মধ্যে রাখেন তবে আপনি সম্ভবত আসল বোতামটি উল্লেখ করতে চাইবেন এবং যখন স্পষ্টভাবে অনুরোধ করা হবে আপনি কেবল একটি অনুলিপি তৈরি করতে চাইবেন। তার মানে আপনার বোতামের ধরণটি একটি রেফারেন্স টাইপ হওয়া উচিত।
ভিউ এবং উইন্ডো কন্ট্রোলারগুলির একটি অনুরূপ উদাহরণ। এগুলি অনুলিপিযোগ্য, অনুমেয়যোগ্য, তবে আপনি যা করতে চান তা কখনই নয়। সেগুলি রেফারেন্স ধরণের হওয়া উচিত।
মডেল ধরনের সম্পর্কে কি? আপনার সিস্টেমে কোনও ব্যবহারকারীকে উপস্থাপন করতে কোনও ইউজার টাইপ, বা কোনও ক্রিম টাইপ ব্যবহারকারীর দ্বারা নেওয়া কোনও পদক্ষেপের প্রতিনিধিত্ব করতে পারে। এগুলি বেশ কপিযোগ্য, সুতরাং এগুলি সম্ভবত মান ধরণের হওয়া উচিত। যাইহোক, আপনি সম্ভবত আপনার প্রোগ্রামের এক জায়গায় করা কোনও ব্যবহারকারীর ক্রাইমের আপডেটগুলি প্রোগ্রামের অন্যান্য অংশে দৃশ্যমান হতে চান। এটি পরামর্শ দেয় যে আপনার ব্যবহারকারীদের কোনও ধরণের ব্যবহারকারী নিয়ামক দ্বারা পরিচালনা করা উচিত যা একটি রেফারেন্স ধরণ হবে । যেমন
struct User {} class UserController { var users: [User] func add(user: User) { ... } func remove(userNamed: String) { ... } func ... }
সংগ্রহগুলি একটি আকর্ষণীয় ঘটনা। এর মধ্যে অ্যারে এবং অভিধানের পাশাপাশি স্ট্রিংয়ের মতো জিনিস রয়েছে। এগুলি কি অনুলিপিযোগ্য? একথাও ঠিক যে। আপনি সহজে এবং প্রায়শই ঘটতে চান এমন কিছু অনুলিপি করছেন? এটা কম পরিষ্কার।
বেশিরভাগ ভাষাগুলি এটিকে "না" বলে এবং তাদের সংগ্রহগুলি রেফারেন্সের ধরণ করে। এটি অবজেক্টিভ-সি এবং জাভা এবং পাইথন এবং জাভাস্ক্রিপ্টে এবং আমি ভাবতে পারি এমন প্রায় প্রতিটি ভাষাতে এটি সত্য। (একটি প্রধান ব্যতিক্রম এসটিএল সংগ্রহের প্রকারের সাথে সি ++, তবে সি ++ ভাষা জগতের বৌদ্ধ পাগল যা অদ্ভুতভাবে সবকিছু করে))
সুইফট "হ্যাঁ" বলেছিলেন যার অর্থ অ্যারে এবং অভিধান এবং স্ট্রিংয়ের মতো ধরণগুলি ক্লাসের পরিবর্তে স্ট্রাক্ট। তারা অ্যাসাইনমেন্টে এবং পরামিতি হিসাবে তাদের পাস করার সময় অনুলিপি করে। অনুলিপিটি সস্তা হওয়া পর্যন্ত এটি সম্পূর্ণরূপে বোধগম্য পছন্দ, যা সুইফ্ট সম্পাদন করার জন্য খুব চেষ্টা করে। ...
আমি ব্যক্তিগতভাবে আমার ক্লাসগুলির নাম রাখি না। আমি সাধারণত ইউজারকন্ট্রোলারের পরিবর্তে আমার ইউজারম্যানেজারের নাম রাখি তবে ধারণাটি একই
ক্লাসটি ব্যবহার করবেন না যখন আপনাকে কোনও ফাংশনের প্রতিটি উদাহরণকে ওভাররাইড করতে হবে অর্থাৎ সেগুলির কোনও ভাগ করা কার্যকারিতা নেই।
সুতরাং পরিবর্তে একটি ক্লাসের বেশ কয়েকটি সাবক্লাস রয়েছে। একটি প্রোটোকলের সাথে সঙ্গতিপূর্ণ এমন কয়েকটি স্ট্রাক ব্যবহার করুন।
স্ট্রাক্টগুলির জন্য আরেকটি যুক্তিসঙ্গত ক্ষেত্রে হ'ল আপনি যখন নিজের পুরানো এবং নতুন মডেলের একটি ব-দ্বীপ / আলাদা করতে চান। উল্লেখের প্রকারের সাহায্যে আপনি বাক্সের বাইরে এটি করতে পারবেন না। মান ধরণের সাথে মিউটেশনগুলি ভাগ করা হয় না।
কিছু সুবিধা:
কাঠামো ক্লাসের চেয়ে অনেক বেশি দ্রুত। এছাড়াও, যদি আপনার উত্তরাধিকার প্রয়োজন তবে আপনার অবশ্যই ক্লাস ব্যবহার করা উচিত। সর্বাধিক গুরুত্বপূর্ণ বিষয় হ'ল শ্রেণি হল রেফারেন্স টাইপ এবং স্ট্রাকচারটি মান ধরণের। উদাহরণ স্বরূপ,
class Flight {
var id:Int?
var description:String?
var destination:String?
var airlines:String?
init(){
id = 100
description = "first ever flight of Virgin Airlines"
destination = "london"
airlines = "Virgin Airlines"
}
}
struct Flight2 {
var id:Int
var description:String
var destination:String
var airlines:String
}
এখন উভয়ের উদাহরণ তৈরি করা যাক।
var flightA = Flight()
var flightB = Flight2.init(id: 100, description:"first ever flight of Virgin Airlines", destination:"london" , airlines:"Virgin Airlines" )
এখন এই উদাহরণটি দুটি ফাংশনে পাস করুন যা আইডি, বর্ণনা, গন্তব্য ইত্যাদি পরিবর্তন করে ..
func modifyFlight(flight:Flight) -> Void {
flight.id = 200
flight.description = "second flight of Virgin Airlines"
flight.destination = "new york"
flight.airlines = "Virgin Airlines"
}
এছাড়াও,
func modifyFlight2(flight2: Flight2) -> Void {
var passedFlight = flight2
passedFlight.id = 200
passedFlight.description = "second flight from virgin airlines"
}
তাই হয়,
modifyFlight(flight: flightA)
modifyFlight2(flight2: flightB)
এখন আমরা যদি ফ্লাইটএ এর আইডি এবং বিবরণ মুদ্রণ করি তবে আমরা পাই
id = 200
description = "second flight of Virgin Airlines"
এখানে আমরা দেখতে পাচ্ছি ফ্লাইটএর আইডি এবং বর্ণনা পরিবর্তিত হয়েছে কারণ পরিবর্তিত পদ্ধতিতে পরামিতিটি পরামিতিটি ফ্লাইটএ অবজেক্টের মেমরি ঠিকানা (রেফারেন্স টাইপ) নির্দেশ করে to
এখন আমরা যদি আমরা পাই FLightB উদাহরণের আইডি এবং বর্ণনা মুদ্রণ করি,
id = 100
description = "first ever flight of Virgin Airlines"
এখানে আমরা দেখতে পাচ্ছি যে ফ্লাইটবি উদাহরণটি পরিবর্তিত হয়নি কারণ পরিবর্তিতফ্লাইট 2 পদ্ধতিতে, ফ্লাইট 2 এর প্রকৃত উদাহরণটি রেফারেন্সের পরিবর্তে (মানের ধরণ) পাস হয়।
Here we can see that the FlightB instance is not changed
Structs
হয় value type
এবং Classes
হয়reference type
একটি value
প্রকার ব্যবহার করুন যখন:
একটি reference
প্রকার ব্যবহার করুন যখন:
অ্যাপল ডকুমেন্টেশনে আরও তথ্য পাওয়া যাবে
https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html
অতিরিক্ত তথ্য
সুইফ মান মান ধরণের স্ট্যাক মধ্যে রাখা হয়। একটি প্রক্রিয়াতে, প্রতিটি থ্রেডের নিজস্ব স্ট্যাকের স্থান রয়েছে, তাই অন্য কোনও থ্রেড আপনার মানের ধরণটি সরাসরি অ্যাক্সেস করতে সক্ষম হবে না। অতএব কোনও রেসের শর্ত, লকস, ডেডলকস বা কোনও সম্পর্কিত থ্রেড সিঙ্ক্রোনাইজেশন জটিলতা নেই।
মান ধরণের গতিশীল মেমরি বরাদ্দ বা রেফারেন্স গণনা প্রয়োজন হয় না, উভয়ই ব্যয়বহুল ক্রিয়াকলাপ। একই সময়ে মান ধরণের পদ্ধতিগুলি স্থিতিশীলভাবে প্রেরণ করা হয়। পারফরম্যান্সের ক্ষেত্রে এগুলি মান ধরণের পক্ষে বিশাল সুবিধা তৈরি করে।
এখানে একটি অনুস্মারক হিসাবে সুইফটের একটি তালিকা
মান প্রকার:
উল্লেখের ধরণ:
মূল্য প্রকারের বনাম রেফারেন্স প্রকারের দৃষ্টিকোণ থেকে প্রশ্নের উত্তর দেওয়া, এই অ্যাপল ব্লগ পোস্ট থেকে এটি খুব সহজ প্রদর্শিত হবে:
একটি মান প্রকার [যেমন স্ট্রাক্ট, এনাম] ব্যবহার করুন যখন:
- উদাহরণের সাথে == এর সাথে ডেটা তুলনা করা অর্থপূর্ণ
- আপনি অনুলিপিগুলি স্বাধীন রাষ্ট্র হিসাবে পেতে চান
- ডেটা একাধিক থ্রেড জুড়ে কোডে ব্যবহৃত হবে
একটি রেফারেন্স টাইপ [উদাহরণস্বরূপ শ্রেণি] ব্যবহার করুন যখন:
- উদাহরণস্বরূপ পরিচয়ের সাথে === তুলনা করা অর্থপূর্ণ
- আপনি ভাগ করে নেওয়া, পরিবর্তনীয় অবস্থা তৈরি করতে চান
এই নিবন্ধে যেমন উল্লেখ করা হয়েছে, কোনও লেখার যোগ্য সম্পত্তি নেই এমন একটি শ্রেণি একটি কাঠামোর সাথে একইভাবে আচরণ করবে, (আমি যুক্ত করব) একটি সতর্কতা: থ্রেড-নিরাপদ মডেলের জন্য স্ট্রাক্টগুলি সেরা - আধুনিক অ্যাপ্লিকেশন আর্কিটেকচারে ক্রমবর্ধমান আসন্ন প্রয়োজন requirement
ক্লাসগুলির সাথে আপনি উত্তরাধিকার পান এবং রেফারেন্স দ্বারা পাস করা হয়, স্ট্রাইকগুলির উত্তরাধিকার থাকে না এবং মান দ্বারা পাস হয়।
সুইফটে দুর্দান্ত ডাব্লুডাব্লুডিসি সেশন রয়েছে, এই নির্দিষ্ট প্রশ্নের উত্তরগুলির মধ্যে একটিতে নিকট বিশদে উত্তর দেওয়া হবে। নিশ্চিত হয়ে নিন যে আপনি এগুলি দেখেছেন, যেহেতু এটি ভাষা গাইড বা আইবুকের পরে আপনাকে আরও দ্রুত গতিতে নিয়ে আসবে।
আমি বলব না যে স্ট্রাইকগুলি কম কার্যকারিতা সরবরাহ করে।
অবশ্যই, একটি পরিবর্তনীয় ফাংশন ব্যতীত স্ব স্ব পরিবর্তনযোগ্য, তবে এটি প্রায় about
উত্তরাধিকার যতক্ষণ না আপনি ভাল পুরানো ধারণাকে আটকে রাখেন যতক্ষণ না প্রতিটি শ্রেণি বিমূর্ত বা চূড়ান্ত হওয়া উচিত।
প্রোটোকল এবং স্ট্রাক্ট হিসাবে চূড়ান্ত ক্লাস হিসাবে বিমূর্ত ক্লাস প্রয়োগ করুন।
স্ট্রাক্টগুলির সম্পর্কে দুর্দান্ত জিনিসটি হ'ল আপনি নিজের ক্ষেত্রগুলিকে ভাগ করে নেওয়া পরিবর্তনীয় রাষ্ট্র তৈরি না করেই পরিবর্তনযোগ্য করে তুলতে পারেন কারণ লেখার অনুলিপি সেই যত্ন নেয় :)
এজন্য নীচের উদাহরণে বৈশিষ্ট্য / ক্ষেত্রগুলি সমস্ত পরিবর্তনযোগ্য, যা আমি জাভা বা সি # বা সুইফ্ট ক্লাসে করব না ।
"উদাহরণ" নামক ফাংশনটির নীচে নীচে কিছুটা নোংরা এবং সোজা ব্যবহারের সাথে উত্তরাধিকারের কাঠামোর উদাহরণ:
protocol EventVisitor
{
func visit(event: TimeEvent)
func visit(event: StatusEvent)
}
protocol Event
{
var ts: Int64 { get set }
func accept(visitor: EventVisitor)
}
struct TimeEvent : Event
{
var ts: Int64
var time: Int64
func accept(visitor: EventVisitor)
{
visitor.visit(self)
}
}
protocol StatusEventVisitor
{
func visit(event: StatusLostStatusEvent)
func visit(event: StatusChangedStatusEvent)
}
protocol StatusEvent : Event
{
var deviceId: Int64 { get set }
func accept(visitor: StatusEventVisitor)
}
struct StatusLostStatusEvent : StatusEvent
{
var ts: Int64
var deviceId: Int64
var reason: String
func accept(visitor: EventVisitor)
{
visitor.visit(self)
}
func accept(visitor: StatusEventVisitor)
{
visitor.visit(self)
}
}
struct StatusChangedStatusEvent : StatusEvent
{
var ts: Int64
var deviceId: Int64
var newStatus: UInt32
var oldStatus: UInt32
func accept(visitor: EventVisitor)
{
visitor.visit(self)
}
func accept(visitor: StatusEventVisitor)
{
visitor.visit(self)
}
}
func readEvent(fd: Int) -> Event
{
return TimeEvent(ts: 123, time: 56789)
}
func example()
{
class Visitor : EventVisitor
{
var status: UInt32 = 3;
func visit(event: TimeEvent)
{
print("A time event: \(event)")
}
func visit(event: StatusEvent)
{
print("A status event: \(event)")
if let change = event as? StatusChangedStatusEvent
{
status = change.newStatus
}
}
}
let visitor = Visitor()
readEvent(1).accept(visitor)
print("status: \(visitor.status)")
}
সুইফটে প্রোটোকল ওরিয়েন্টেড প্রোগ্রামিং নামে পরিচিত একটি নতুন প্রোগ্রামিং প্যাটার্ন চালু করা হয়েছে।
সৃষ্টিশীল প্যাটার্ন:
দ্রুতগতিতে, স্ট্রাক্ট একটি মান ধরণের যা স্বয়ংক্রিয়ভাবে ক্লোন হয়ে যায়। অতএব আমরা বিনামূল্যে প্রোটোটাইপ প্যাটার্ন বাস্তবায়নের জন্য প্রয়োজনীয় আচরণটি পাই।
যেখানে শ্রেণীর রেফারেন্স ধরন, যা স্বয়ংক্রিয়ভাবে নিয়োগ সময় ক্লোন না হয়। প্রোটোটাইপ প্যাটার্ন বাস্তবায়নের জন্য, ক্লাসগুলিকে NSCopying
প্রোটোকল গ্রহণ করতে হবে ।
অগভীর অনুলিপি কেবল সেই রেফারেন্সকেই সদৃশ করে, যা সেই বিষয়গুলিকে নির্দেশ করে যেখানে গভীর অনুলিপি সদৃশ বস্তুর রেফারেন্স।
বাস্তবায়নকারী গভীর কপি প্রতিটি রেফারেন্স টাইপ একটি ক্লান্তিকর কাজের পরিণত হয়েছে। যদি শ্রেণিতে আরও রেফারেন্স প্রকার অন্তর্ভুক্ত থাকে তবে আমাদের প্রতিটি রেফারেন্স বৈশিষ্ট্যের জন্য প্রোটোটাইপ প্যাটার্ন প্রয়োগ করতে হবে। এবং তারপরে আমাদের NSCopying
প্রোটোকল প্রয়োগ করে পুরো অবজেক্ট গ্রাফটি অনুলিপি করতে হবে ।
class Contact{
var firstName:String
var lastName:String
var workAddress:Address // Reference type
}
class Address{
var street:String
...
}
স্ট্রাক্টস এবং এনামগুলি ব্যবহার করে আমরা আমাদের কোডটিকে সহজ করে দিয়েছি কারণ আমাদের অনুলিপি যুক্তি প্রয়োগ করতে হবে না।
অনেক কোকো এপিআই-এর জন্য এনএসবজেক্ট সাবক্লাস প্রয়োজন, যা আপনাকে ক্লাস ব্যবহারে বাধ্য করে। তবে এগুলি বাদে, আপনি স্ট্রাক্ট / এনাম মান ধরণের বা শ্রেণীর রেফারেন্স টাইপ ব্যবহার করবেন কিনা তা সিদ্ধান্ত নিতে অ্যাপলের সুইফ্ট ব্লগ থেকে নিম্নলিখিত কেসগুলি ব্যবহার করতে পারেন।
এই উত্তরের প্রতি দৃষ্টি আকর্ষণ না করার একটি বিষয় হ'ল একটি কাঠাম বনাম কাঠামো ধারণ করে একটি চলক let
কিছুক্ষণ এখনও অবজেক্টের বৈশিষ্ট্যগুলিতে পরিবর্তনের অনুমতি দিতে পারে, যখন আপনি স্ট্রাক্ট দিয়ে এটি করতে পারবেন না।
আপনি যদি ভেরিয়েবলটি অন্য কোনও অবজেক্টের দিকে নির্দেশ না করতে চান তবে এটি দরকারী, তবে এখনও অবজেক্টটি সংশোধন করা দরকার, অর্থাত্ একের পর এক আপডেট করতে চান এমন অনেক ইনস্ট্যান্স ভেরিয়েবল থাকার ক্ষেত্রে। যদি এটি একটি কাঠামো হয় তবে আপনাকে অবশ্যই এটি করতে গিয়ে ভেরিয়েবলটিকে অন্য কোনও বস্তুর সাথে পুনরায় সেট করার অনুমতি দিতে হবে var
, যেহেতু সুইফটে ধ্রুবক মান ধরণের সঠিকভাবে শূন্য পরিবর্তনের অনুমতি দেয়, যখন রেফারেন্সের ধরণগুলি (শ্রেণিগুলি) এভাবে আচরণ করে না।
স্ট্রাক্ট যেমন মূল্য প্রকারের হয় এবং আপনি খুব সহজেই স্মৃতি তৈরি করতে পারেন যা স্ট্যাকগুলিতে সঞ্চয় করে ruct স্ট্রাক্ট সহজেই অ্যাক্সেসযোগ্য হতে পারে এবং কাজের সুযোগের পরে এটি স্ট্যাকের মেমরি থেকে স্ট্যাকের শীর্ষ থেকে পপের মাধ্যমে সহজেই বিচ্ছিন্ন হয়ে যায়। অন্যদিকে শ্রেণি হল একটি রেফারেন্স টাইপ যা হিপগুলিতে সঞ্চয় করে এবং এক শ্রেণীর বস্তুতে করা পরিবর্তনগুলি অন্য বস্তুর উপর প্রভাব ফেলবে কারণ সেগুলি দৃly়ভাবে সংযুক্ত এবং রেফারেন্স প্রকার। কাঠামোর সমস্ত সদস্যই পাবলিক যেখানে শ্রেণীর সমস্ত সদস্য ব্যক্তিগত থাকে ।
কাঠামোর অসুবিধাগুলি হ'ল এটি উত্তরাধিকারসূত্রে প্রাপ্ত হতে পারে না।
স্ট্রাকচার এবং ক্লাস হ'ল ইউজার ডেফ্টেড ডেটা টাইপ
ডিফল্টরূপে, কাঠামোটি সর্বজনীন যেখানে শ্রেণি ব্যক্তিগত হয়
ক্লাসটি এনক্যাপসুলেশনের মূল প্রয়োগ করে
একটি শ্রেণীর অবজেক্টগুলি হিপ মেমোরিতে তৈরি করা হয়
পুনরায় ব্যবহারযোগ্যতার জন্য শ্রেণি ব্যবহৃত হয় যেখানে কাঠামো একই কাঠামোর মধ্যে ডেটা গোষ্ঠীকরণের জন্য ব্যবহৃত হয়
কাঠামোর ডেটা সদস্যদের সরাসরি আরম্ভ করা যায় না তবে তারা কাঠামোর বাইরের দ্বারা নির্ধারিত হতে পারে
ক্লাস ডেটা সদস্যদের কম প্যারামিটার কম কনস্ট্রাক্টর দ্বারা সূচনা করা যেতে পারে এবং প্যারামিটারাইজড কনস্ট্রাক্টর দ্বারা নির্ধারিত হতে পারে