দ্রুতগতিতে দুটি সমতা অপারেটর রয়েছে বলে মনে হয়: ডাবল সমান ( ==
) এবং ট্রিপল সমান ( ===
), উভয়ের মধ্যে পার্থক্য কী?
দ্রুতগতিতে দুটি সমতা অপারেটর রয়েছে বলে মনে হয়: ডাবল সমান ( ==
) এবং ট্রিপল সমান ( ===
), উভয়ের মধ্যে পার্থক্য কী?
উত্তর:
সংক্ষেপে:
==
অপারেটর চেক করে যদি তাদের উদাহরণগুলির মানগুলি সমান হয়, "equal to"
===
রেফারেন্সগুলি একই উদাহরণটিকে নির্দেশ করে কিনা অপারেটর চেক করে "identical to"
দীর্ঘ উত্তর:
ক্লাসগুলি রেফারেন্সের ধরণ, একাধিক ধ্রুবক এবং ভেরিয়েবলের পক্ষে পর্দার পিছনে কোনও শ্রেণীর একই একক উদাহরণটি উল্লেখ করা সম্ভব। ক্লাস রেফারেন্স রান টাইম স্ট্যাক (আরটিএস) এ থাকে এবং তাদের উদাহরণ মেমরির হিপ এরিয়ায় থাকে। আপনি যখন ==
এটির সাথে সাম্যতা নিয়ন্ত্রণ করেন তার অর্থ যদি তাদের দৃষ্টান্তগুলি একে অপরের সাথে সমান হয়। সমান হওয়ার জন্য এটি একই উদাহরণ হওয়ার দরকার নেই। এর জন্য আপনাকে আপনার কাস্টম শ্রেণিতে সমতার মানদণ্ড সরবরাহ করতে হবে। ডিফল্টরূপে, কাস্টম ক্লাস এবং কাঠামো সমানতা অপারেটরদের একটি ডিফল্ট বাস্তবায়ন, "সমান" অপারেটর হিসাবে পরিচিত না পান ==
এবং অপারেটর "থেকে সমান নয়" !=
। এটি করার জন্য আপনার কাস্টম ক্লাসের Equatable
প্রোটোকলটি মেনে চলতে হবে এবং এটিstatic func == (lhs:, rhs:) -> Bool
কার্যকারিতা রয়েছে
আসুন উদাহরণটি দেখুন:
class Person : Equatable {
let ssn: Int
let name: String
init(ssn: Int, name: String) {
self.ssn = ssn
self.name = name
}
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.ssn == rhs.ssn
}
}
P.S.:
যেহেতু ssn (সামাজিক সুরক্ষা নম্বর) একটি অনন্য সংখ্যা, আপনার নামটি সমান বা না হলে আপনার তুলনা করার দরকার নেই।
let person1 = Person(ssn: 5, name: "Bob")
let person2 = Person(ssn: 5, name: "Bob")
if person1 == person2 {
print("the two instances are equal!")
}
যদিও person1 এবং person2 রেফারেন্সগুলি হিপ অঞ্চলে দুটি পৃথক দৃষ্টান্ত নির্দেশ করে, তাদের উদাহরণগুলি সমান কারণ তাদের এসএসএন সংখ্যা সমান। সুতরাং আউটপুট হবেthe two instance are equal!
if person1 === person2 {
//It does not enter here
} else {
print("the two instances are not identical!")
}
===
অপারেটর চেক করে যদি রেফারেন্স একই উদাহরণ দেখায় "identical to"
,। যেহেতু ব্যক্তি 1 এবং ব্যক্তি 2 এর হিপ অঞ্চলে দুটি পৃথক উদাহরণ রয়েছে, সেগুলি অভিন্ন এবং আউটপুট নয়the two instance are not identical!
let person3 = person1
P.S:
শ্রেণিগুলি রেফারেন্সের ধরণ এবং ব্যক্তি 1 এর রেফারেন্সটি এই অ্যাসাইনমেন্ট ক্রিয়াকলাপের সাথে person3 এ অনুলিপি করা হয়, সুতরাং উভয় উল্লেখগুলি হিপ অঞ্চলে একই উদাহরণ দেখায়।
if person3 === person1 {
print("the two instances are identical!")
}
তারা অভিন্ন এবং আউটপুট হবে the two instances are identical!
!==
এবং ===
পরিচয় অপারেটর এবং দুটি বস্তুর একই রেফারেন্স রয়েছে কিনা তা নির্ধারণ করতে ব্যবহৃত হয়।
সুইফট দুটি পরিচয় অপারেটরও সরবরাহ করে (=== এবং! ==), যা আপনি দুটি বস্তুর উল্লেখ উভয় একই বস্তুর উদাহরণকে উল্লেখ করে কিনা তা পরীক্ষা করতে ব্যবহার করেন।
এর উত্স: অ্যাপল ইনক। "দ্য সুইফ্ট প্রোগ্রামিং ভাষা।" iBooks। https://itun.es/us/jEUH0.l
var
বা let
) একটি অনন্য অনুলিপি - সুতরাং পয়েন্টার তৈরি করা অর্থহীন কারণ আপনি যে মানটিকে পয়েন্টার করেছেন সেটিই আপনি প্রথমে তৈরির চেয়ে আলাদা মান। অন্যটি হ'ল সুইফ্টের মান শব্দার্থবিজ্ঞানের সংজ্ঞা স্টোরেজটি দূরে সরিয়ে দেয় - সংকলকটি অনুকূলিতকরণের জন্য নিখরচায়, যেখানে এটি ব্যবহার করা হয় না এমন লাইনের বাইরে অ্যাক্সেসযোগ্য কোনও মেমরি লোকেশনে আপনার মানটি কখনও সংরক্ষণ না করে (রেজিস্টার, নির্দেশনা এনকোডিং ইত্যাদি)।
উভয় উদ্দেশ্য সি এবং সুইফট সালে ==
এবং !=
সংখ্যা মানের জন্য মান সমতার জন্য অপারেটরদের পরীক্ষা (যেমন, NSInteger
, NSUInteger
, int
, উদ্দেশ্য সি এবং Int
, UInt
, সুইফট মধ্যে ইত্যাদি)। অবজেক্টের জন্য (এনএসবজেক্ট / এনএস নাম্বার এবং সাবজেক্টস অবজেক্টিভ-সি এবং সুইফটে রেফারেন্স টাইপ) ==
এবং !=
পরীক্ষা করুন যে অবজেক্টস / রেফারেন্স টাইপগুলি একই রকম জিনিস - যেমন, একই হ্যাশ মান - বা যথাক্রমে একই অভিন্ন জিনিস নয় ।
let a = NSObject()
let b = NSObject()
let c = a
a == b // false
a == c // true
সুইফ্টের পরিচয় সমতা অপারেটর ===
এবং , এবং !==
রেফারেন্সিয়াল সমতা পরীক্ষা করে - এবং সম্ভবত সম্ভবত রেফারেন্সিয়াল ইক্যুটি অপারেটরস আইএমও বলা উচিত ।
a === b // false
a === c // true
এটি আরও উল্লেখ করার মতো যে সুইফটে কাস্টম রেফারেন্স প্রকারগুলি (যে সমতুল্য হিসাবে মান্য করে এমন একটি শ্রেণীর সাবক্লাস করে না) স্বয়ংক্রিয়ভাবে অপারেটরের সমান প্রয়োগ করে না, তবে পরিচয়ের সমতা অপারেটরগুলি এখনও প্রয়োগ করে। এছাড়াও, প্রয়োগের মাধ্যমে ==
, !=
স্বয়ংক্রিয়ভাবে প্রয়োগ করা হয়।
class MyClass: Equatable {
let myProperty: String
init(s: String) {
myProperty = s
}
}
func ==(lhs: MyClass, rhs: MyClass) -> Bool {
return lhs.myProperty == rhs.myProperty
}
let myClass1 = MyClass(s: "Hello")
let myClass2 = MyClass(s: "Hello")
myClass1 == myClass2 // true
myClass1 != myClass2 // false
myClass1 === myClass2 // false
myClass1 !== myClass2 // true
এই সমতা অপারেটরগুলি অন্য ধরনের যেমন উভয় ভাষায় কাঠামোর জন্য প্রয়োগ করা হয় না। যাইহোক, কাস্টম অপারেটরগুলি সুইফটে তৈরি করা যেতে পারে, উদাহরণস্বরূপ, আপনাকে সিজিপয়েন্টের সমতা পরীক্ষা করতে অপারেটর তৈরি করতে সক্ষম করবে।
infix operator <==> { precedence 130 }
func <==> (lhs: CGPoint, rhs: CGPoint) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
let point1 = CGPoint(x: 1.0, y: 1.0)
let point2 = CGPoint(x: 1.0, y: 1.0)
point1 <==> point2 // true
==
NSNumber
উদ্দেশ্য-সি-তে সমতার জন্য পরীক্ষা করে না । NSNumber
এটি NSObject
তাই এটি পরিচয়ের জন্য পরীক্ষা করে। এটি SOMETIMES কাজ করার কারণটি হ'ল ট্যাগ পয়েন্টার / ক্যাশেড অবজেক্ট ল্যাটারালগুলি। লিটারাল তুলনা করার সময় এটি যথেষ্ট পরিমাণে এবং 32-বিট ডিভাইসে ব্যর্থ হবে।
===
(বা !==
)==
OBJ-সি (পয়েন্টার সমতা) এ।==
(বা !=
)isEqual:
ওবজে-সি আচরণে ডিফল্টের মতো ।এখানে আমি তিনটি দৃষ্টান্ত তুলনা করছি (ক্লাস একটি রেফারেন্স টাইপ)
class Person {}
let person = Person()
let person2 = person
let person3 = Person()
person === person2 // true
person === person3 // false
isEqual:
override func isEqual(_ object: Any?) -> Bool {}
সুইফ্টগুলির সাথে সূক্ষ্মতা রয়েছে ===
যা নিছক পয়েন্টার গাণিতিকের বাইরে। উদ্দেশ্য-সিতে থাকা অবস্থায় আপনি যে কোনও দুটি পয়েন্টার (অর্থাত্ NSObject *
) এর সাথে তুলনা করতে সক্ষম হন==
কারণ সংকলনের সময় প্রকারগুলি আরও বেশি ভূমিকা পালন করে বলে সুইফ্টে আর এটি সত্য নয়।
একটি খেলার মাঠ আপনাকে দেবে
1 === 2 // false
1 === 1 // true
let one = 1 // 1
1 === one // compile error: Type 'Int' does not conform to protocol 'AnyObject'
1 === (one as AnyObject) // true (surprisingly (to me at least))
স্ট্রিংগুলির সাথে আমাদের এটিতে অভ্যস্ত হতে হবে:
var st = "123" // "123"
var ns = (st as NSString) // "123"
st == ns // true, content equality
st === ns // compile error
ns === (st as NSString) // false, new struct
ns === (st as AnyObject) // false, new struct
(st as NSString) === (st as NSString) // false, new structs, bridging is not "free" (as in "lunch")
NSString(string:st) === NSString(string:st) // false, new structs
var st1 = NSString(string:st) // "123"
var st2 = st1 // "123"
st1 === st2 // true
var st3 = (st as NSString) // "123"
st1 === st3 // false
(st as AnyObject) === (st as AnyObject) // false
তবে তারপরে আপনিও মজা করতে পারেন:
var st4 = st // "123"
st4 == st // true
st4 += "5" // "1235"
st4 == st // false, not quite a reference, copy on write semantics
আমি নিশ্চিত আপনি আরও মজার ঘটনা সম্পর্কে ভাবতে পারেন :-)
সুইফট 3 এর জন্য আপডেট (যাকুব ট্রুহ্লির মন্তব্য অনুসারে)
1===2 // Compiler error: binary operator '===' cannot be applied to two 'Int' operands
(1 as AnyObject) === (2 as AnyObject) // false
let two = 2
(2 as AnyObject) === (two as AnyObject) // false (rather unpleasant)
(2 as AnyObject) === (2 as AnyObject) // false (this makes it clear that there are new objects being generated)
এটি দেখতে আরও কিছুটা সামঞ্জস্যপূর্ণ দেখায় Type 'Int' does not conform to protocol 'AnyObject'
তবে আমরা পরে পাই
type(of:(1 as AnyObject)) // _SwiftTypePreservingNSNumber.Type
তবে স্পষ্ট রূপান্তরটি স্পষ্ট করে দেয় যে এখানে কিছু চলছে। স্ট্রিং-সাইডে জিনিসগুলি NSString
এখনও আমাদের হিসাবে উপলব্ধ থাকবে import Cocoa
। তাহলে আমাদের হবে
var st = "123" // "123"
var ns = (st as NSString) // "123"
st == ns // Compile error with Fixit: 'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?
st == ns as String // true, content equality
st === ns // compile error: binary operator '===' cannot be applied to operands of type 'String' and 'NSString'
ns === (st as NSString) // false, new struct
ns === (st as AnyObject) // false, new struct
(st as NSString) === (st as NSString) // false, new structs, bridging is not "free" (as in "lunch")
NSString(string:st) === NSString(string:st) // false, new objects
var st1 = NSString(string:st) // "123"
var st2 = st1 // "123"
st1 === st2 // true
var st3 = (st as NSString) // "123"
st1 === st3 // false
(st as AnyObject) === (st as AnyObject) // false
এটি এখনও দুটি স্ট্রিং ক্লাস নিয়ে বিভ্রান্তিকর, তবে অন্তর্নিহিত রূপান্তরটি বাদ দেওয়া সম্ভবত এটি আরও কিছুটা স্পষ্ট করে তুলবে ।
===
তুলনা করতে অপারেটর ব্যবহার করতে পারবেন না Ints
। সুইফট ৩ এ নয়
===
স্ট্রাইকগুলির জন্য অর্থহীন কারণ তারা মান ধরণের। বিশেষত, আপনার তিনটি ধরণের কথা মনে রাখতে হবে: আক্ষরিক প্রকারগুলি, যেমন 1 বা "ফু", যা কোনও পরিবর্তনশীলের সাথে আবদ্ধ হয় নি এবং সাধারণত কেবল সংকলনকে প্রভাবিত করে যেহেতু আপনি সাধারণত রানটাইমের সময় তাদের সাথে ডিল করেন না; কাঠামোর ধরণের যেমন Int
এবং String
আপনি যখন কোনও ভেরিয়েবলকে আক্ষরিক অর্পণ করেন তখন কি পাবেন এবং ক্লাস যেমন AnyObject
এবং NSString
।
উদাহরণস্বরূপ, আপনি যদি শ্রেণীর দুটি উদাহরণ তৈরি করেন যেমন myClass
:
var inst1 = myClass()
var inst2 = myClass()
আপনি এই দৃষ্টান্ত তুলনা করতে পারেন,
if inst1 === inst2
উদাহৃত:
যা আপনি দুটি বস্তুর উল্লেখ উভয় একই বস্তুর উদাহরণকে উল্লেখ করে কিনা তা পরীক্ষা করতে ব্যবহার করেন।
এর উত্স: অ্যাপল ইনক। "দ্য সুইফ্ট প্রোগ্রামিং ভাষা।" iBooks। https://itun.es/sk/jEUH0.l
সুইফটে আমাদের রয়েছে === সিম্বল যার অর্থ উভয় বস্তু একই রেফারেন্সের একই ঠিকানা উল্লেখ করছে
class SomeClass {
var a: Int;
init(_ a: Int) {
self.a = a
}
}
var someClass1 = SomeClass(4)
var someClass2 = SomeClass(4)
someClass1 === someClass2 // false
someClass2 = someClass1
someClass1 === someClass2 // true
Any
অবজেক্ট সম্পর্কিত কেবল একটি ছোট্ট অবদান ।
আমি চারদিকে ইউনিট পরীক্ষা নিয়ে কাজ করছিলাম NotificationCenter
, যা ব্যবহার করেAny
সাম্যতার জন্য তুলনা করতে চেয়েছি এমন পরামিতি হিসাবে ।
তবে যেহেতু Any
সমতা অপারেশনে ব্যবহার করা যায় না তাই এটি পরিবর্তন করা দরকার ছিল। শেষ পর্যন্ত, আমি নিম্নলিখিত পদ্ধতির উপর স্থির হয়েছি, যা আমাকে আমার নির্দিষ্ট পরিস্থিতিতে সাম্যতা পেতে দেয়, এখানে সরল উদাহরণ দিয়ে দেখানো হয়েছে:
func compareTwoAny(a: Any, b: Any) -> Bool {
return ObjectIdentifier(a as AnyObject) == ObjectIdentifier(b as AnyObject)
}
এই ফাংশনটি সুবিধা গ্রহণ করে অবজেক্টআইডিটিফায়ারের যা আমাকে পরীক্ষার অনুমতি দিয়ে অবজেক্টের জন্য একটি অনন্য ঠিকানা সরবরাহ করে।
একটি আইটেম যদিও সম্পর্কে নোট করা ObjectIdentifier
উপরের লিঙ্কে প্রতি অ্যাপল :
সুইফটে, কেবল শ্রেণীর উদাহরণ এবং মেটাটাইপগুলির অনন্য পরিচয় রয়েছে। স্ট্রাকস, এনাম, ফাংশন বা টিপলসের জন্য পরিচয়ের কোনও ধারণা নেই।
==
দুটি ভেরিয়েবল সমান কিনা তা পরীক্ষা করতে ব্যবহৃত হয়
2 == 2
। তবে ===
এটির ক্ষেত্রে সমতার অর্থ দাঁড়ায় অর্থাত্ যদি ক্লাসের ক্ষেত্রে দু'টি উদাহরণ একই বস্তুর উদাহরণকে উল্লেখ করে তবে এমন একটি রেফারেন্স তৈরি হয় যা অন্যান্য বহু উদাহরণ দ্বারা ধারণ করা হয়।
সুইফট 4: ইউনিট টেস্ট ব্যবহার করে আর একটি উদাহরণ যা কেবলমাত্র === নিয়ে কাজ করে
দ্রষ্টব্য: নীচে পরীক্ষা == দিয়ে ব্যর্থ হয়, === এর সাথে কাজ করে
func test_inputTextFields_Delegate_is_ViewControllerUnderTest() {
//instantiate viewControllerUnderTest from Main storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)
viewControllerUnderTest = storyboard.instantiateViewController(withIdentifier: "StoryBoardIdentifier") as! ViewControllerUnderTest
let _ = viewControllerUnderTest.view
XCTAssertTrue(viewControllerUnderTest.inputTextField.delegate === viewControllerUnderTest)
}
এবং শ্রেণি হচ্ছে
class ViewControllerUnderTest: UIViewController, UITextFieldDelegate {
@IBOutlet weak var inputTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
inputTextField.delegate = self
}
}
ইউনিট টেস্টে ত্রুটিটি যদি আপনি == ব্যবহার করেন তবে Binary operator '==' cannot be applied to operands of type 'UITextFieldDelegate?' and 'ViewControllerUnderTest!'
==
হয়isEqual:
, অথবা বর্গ সংজ্ঞায়িত শব্দার্থিক সমানতা।===
সুইফট হয়==
পয়েন্টার সমতা, বা বস্তুর পরিচয় - (OBJ) সি।