== এবং === এর মধ্যে পার্থক্য


300

দ্রুতগতিতে দুটি সমতা অপারেটর রয়েছে বলে মনে হয়: ডাবল সমান ( ==) এবং ট্রিপল সমান ( ===), উভয়ের মধ্যে পার্থক্য কী?

উত্তর:


149

সংক্ষেপে:

== অপারেটর চেক করে যদি তাদের উদাহরণগুলির মানগুলি সমান হয়, "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!


248

!==এবং ===পরিচয় অপারেটর এবং দুটি বস্তুর একই রেফারেন্স রয়েছে কিনা তা নির্ধারণ করতে ব্যবহৃত হয়।

সুইফট দুটি পরিচয় অপারেটরও সরবরাহ করে (=== এবং! ==), যা আপনি দুটি বস্তুর উল্লেখ উভয় একই বস্তুর উদাহরণকে উল্লেখ করে কিনা তা পরীক্ষা করতে ব্যবহার করেন।

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


49
হা. ObjC থেকে আসছে, ==হয় isEqual:, অথবা বর্গ সংজ্ঞায়িত শব্দার্থিক সমানতা। ===সুইফট হয় ==পয়েন্টার সমতা, বা বস্তুর পরিচয় - (OBJ) সি।
রিক্সার

@ চালক না ডান 'মানগুলির একটি স্মৃতি অবস্থান আছে? আমি শেষ পর্যন্ত তারা স্মৃতি কোথাও আছেন। আপনি কি কখনও তাদের তুলনা করতে পারবেন না? বা তাদের স্মৃতি অবস্থান কোনও অর্থবহ মান দেয় না ?
মধু

2
ভাষা কীভাবে বনাম মেমরির মূল্য নির্ধারণ করে সে সম্পর্কে ভাবার জন্য কমপক্ষে দুটি উপায় রয়েছে। একটি হ'ল একটি নামের প্রতি প্রতিটি বাঁধাই ( varবা let) একটি অনন্য অনুলিপি - সুতরাং পয়েন্টার তৈরি করা অর্থহীন কারণ আপনি যে মানটিকে পয়েন্টার করেছেন সেটিই আপনি প্রথমে তৈরির চেয়ে আলাদা মান। অন্যটি হ'ল সুইফ্টের মান শব্দার্থবিজ্ঞানের সংজ্ঞা স্টোরেজটি দূরে সরিয়ে দেয় - সংকলকটি অনুকূলিতকরণের জন্য নিখরচায়, যেখানে এটি ব্যবহার করা হয় না এমন লাইনের বাইরে অ্যাক্সেসযোগ্য কোনও মেমরি লোকেশনে আপনার মানটি কখনও সংরক্ষণ না করে (রেজিস্টার, নির্দেশনা এনকোডিং ইত্যাদি)।
রিক্সার

62

উভয় উদ্দেশ্য সি এবং সুইফট সালে ==এবং !=সংখ্যা মানের জন্য মান সমতার জন্য অপারেটরদের পরীক্ষা (যেমন, 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

3
দুঃখিত, তবে ওবজে-সিতে == অপারেটর ইক্যুয়ালিটির জন্য তুলনা করে না, বরং সি-এর মতো - পয়েন্টার রেফারেন্সের সাথে (বস্তুর পরিচয়) তুলনা করে।
মোটি শ্নের

==NSNumberউদ্দেশ্য-সি-তে সমতার জন্য পরীক্ষা করে না । NSNumberএটি NSObjectতাই এটি পরিচয়ের জন্য পরীক্ষা করে। এটি SOMETIMES কাজ করার কারণটি হ'ল ট্যাগ পয়েন্টার / ক্যাশেড অবজেক্ট ল্যাটারালগুলি। লিটারাল তুলনা করার সময় এটি যথেষ্ট পরিমাণে এবং 32-বিট ডিভাইসে ব্যর্থ হবে।
অ্যাক্যাটিক

45

দ্রুত এবং 3 এর উপরে

===(বা !==)

  • মানগুলি অভিন্ন কিনা তা পরীক্ষা করে (উভয় একই মেমরি ঠিকানার দিকে নির্দেশ করে)
  • রেফারেন্স ধরণের তুলনা করা
  • ভালো লেগেছে ==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 {}
থমাস ইলিয়ট

37

সুইফ্টগুলির সাথে সূক্ষ্মতা রয়েছে ===যা নিছক পয়েন্টার গাণিতিকের বাইরে। উদ্দেশ্য-সিতে থাকা অবস্থায় আপনি যে কোনও দুটি পয়েন্টার (অর্থাত্ 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

এটি এখনও দুটি স্ট্রিং ক্লাস নিয়ে বিভ্রান্তিকর, তবে অন্তর্নিহিত রূপান্তরটি বাদ দেওয়া সম্ভবত এটি আরও কিছুটা স্পষ্ট করে তুলবে ।


2
আপনি ===তুলনা করতে অপারেটর ব্যবহার করতে পারবেন না Ints। সুইফট ৩ এ নয়
জাকুব ট্রুহলি

আপনি যখনই বলছেন একটি "নতুন কাঠামো" তৈরি হচ্ছে, আসলে যা ঘটছে তা একটি নতুন অবজেক্ট (একটি শ্রেণির ধরণের) তৈরি হচ্ছে। ===স্ট্রাইকগুলির জন্য অর্থহীন কারণ তারা মান ধরণের। বিশেষত, আপনার তিনটি ধরণের কথা মনে রাখতে হবে: আক্ষরিক প্রকারগুলি, যেমন 1 বা "ফু", যা কোনও পরিবর্তনশীলের সাথে আবদ্ধ হয় নি এবং সাধারণত কেবল সংকলনকে প্রভাবিত করে যেহেতু আপনি সাধারণত রানটাইমের সময় তাদের সাথে ডিল করেন না; কাঠামোর ধরণের যেমন Intএবং Stringআপনি যখন কোনও ভেরিয়েবলকে আক্ষরিক অর্পণ করেন তখন কি পাবেন এবং ক্লাস যেমন AnyObjectএবং NSString
সাগরঝা

12

উদাহরণস্বরূপ, আপনি যদি শ্রেণীর দুটি উদাহরণ তৈরি করেন যেমন myClass:

var inst1 = myClass()
var inst2 = myClass()

আপনি এই দৃষ্টান্ত তুলনা করতে পারেন,

if inst1 === inst2

উদাহৃত:

যা আপনি দুটি বস্তুর উল্লেখ উভয় একই বস্তুর উদাহরণকে উল্লেখ করে কিনা তা পরীক্ষা করতে ব্যবহার করেন।

এর উত্স: অ্যাপল ইনক। "দ্য সুইফ্ট প্রোগ্রামিং ভাষা।" iBooks। https://itun.es/sk/jEUH0.l


11

সুইফটে আমাদের রয়েছে === সিম্বল যার অর্থ উভয় বস্তু একই রেফারেন্সের একই ঠিকানা উল্লেখ করছে

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

4

Anyঅবজেক্ট সম্পর্কিত কেবল একটি ছোট্ট অবদান ।

আমি চারদিকে ইউনিট পরীক্ষা নিয়ে কাজ করছিলাম NotificationCenter, যা ব্যবহার করেAny সাম্যতার জন্য তুলনা করতে চেয়েছি এমন পরামিতি হিসাবে ।

তবে যেহেতু Anyসমতা অপারেশনে ব্যবহার করা যায় না তাই এটি পরিবর্তন করা দরকার ছিল। শেষ পর্যন্ত, আমি নিম্নলিখিত পদ্ধতির উপর স্থির হয়েছি, যা আমাকে আমার নির্দিষ্ট পরিস্থিতিতে সাম্যতা পেতে দেয়, এখানে সরল উদাহরণ দিয়ে দেখানো হয়েছে:

func compareTwoAny(a: Any, b: Any) -> Bool {
    return ObjectIdentifier(a as AnyObject) == ObjectIdentifier(b as AnyObject)
}

এই ফাংশনটি সুবিধা গ্রহণ করে অবজেক্টআইডিটিফায়ারের যা আমাকে পরীক্ষার অনুমতি দিয়ে অবজেক্টের জন্য একটি অনন্য ঠিকানা সরবরাহ করে।

একটি আইটেম যদিও সম্পর্কে নোট করা ObjectIdentifierউপরের লিঙ্কে প্রতি অ্যাপল :

সুইফটে, কেবল শ্রেণীর উদাহরণ এবং মেটাটাইপগুলির অনন্য পরিচয় রয়েছে। স্ট্রাকস, এনাম, ফাংশন বা টিপলসের জন্য পরিচয়ের কোনও ধারণা নেই।


2

==দুটি ভেরিয়েবল সমান কিনা তা পরীক্ষা করতে ব্যবহৃত হয় 2 == 2। তবে ===এটির ক্ষেত্রে সমতার অর্থ দাঁড়ায় অর্থাত্ যদি ক্লাসের ক্ষেত্রে দু'টি উদাহরণ একই বস্তুর উদাহরণকে উল্লেখ করে তবে এমন একটি রেফারেন্স তৈরি হয় যা অন্যান্য বহু উদাহরণ দ্বারা ধারণ করা হয়।


1

সুইফট 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!'

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.