কীভাবে সুইফটে সম্পর্কিত মানটিকে উপেক্ষা করে যুক্ত মানগুলির সাথে এনামের তুলনা করা যায়?


90

সম্পর্কিত মানগুলির সাথে সুইফট এনামগুলির সাম্যতা কীভাবে পরীক্ষা করতে হয় তা পড়ার পরে , আমি নিম্নলিখিত এনাম প্রয়োগ করেছি:

enum CardRank {
    case Number(Int)
    case Jack
    case Queen
    case King
    case Ace
}

func ==(a: CardRank, b: CardRank) -> Bool {
    switch (a, b) {
    case (.Number(let a), .Number(let b))   where a == b: return true
    case (.Jack, .Jack): return true
    case (.Queen, .Queen): return true
    case (.King, .King): return true
    case (.Ace, .Ace): return true
    default: return false
    }
}

নিম্নলিখিত কোডটি কাজ করে:

let card: CardRank = CardRank.Jack
if card == CardRank.Jack {
    print("You played a jack!")
} else if card == CardRank.Number(2) {
    print("A two cannot be played at this time.")
}

তবে এটি সংকলন করে না:

let number = CardRank.Number(5)
if number == CardRank.Number {
    print("You must play a face card!")
}

... এবং এটি নিম্নলিখিত ত্রুটি বার্তা দেয়:

বাইনারি অপারেটর '==' 'কার্ডর্যাঙ্ক' এবং '(ইনট) -> কার্ডর্যাঙ্ক' প্রকারের অপারেন্ডগুলিতে প্রয়োগ করা যাবে না

আমি এটি ধরে নিচ্ছি কারণ এটি একটি সম্পূর্ণ প্রকারের প্রত্যাশা করছে এবং একটি সম্পূর্ণ ধরণের CardRank.Numberনির্দিষ্ট করে না, যেখানে হয়েছে CardRank.Number(2)। যাইহোক, এই ক্ষেত্রে, আমি এটি কোনও সংখ্যার সাথে মেলাতে চাই ; শুধু একটি নির্দিষ্ট না।

স্পষ্টতই আমি একটি স্যুইচ স্টেটমেন্ট ব্যবহার করতে পারি, তবে ==অপারেটর বাস্তবায়নের পুরো বিষয়টিটি ছিল এই ভার্জোজ সমাধানটি এড়ানো:

switch number {
case .Number:
    print("You must play a face card!")
default:
    break
}

কোনও এনামের সাথে সম্পর্কিত মানটিকে উপেক্ষা করার সাথে সম্পর্কিত মানগুলির সাথে তুলনা করার কোনও উপায় আছে কি?

দ্রষ্টব্য: আমি উপলব্ধি করেছি যে ==পদ্ধতিতে আমি কেসটি পরিবর্তিত করতে পারি case (.Number, .Number): return true, তবে, যদিও এটি সঠিকভাবে ফিরে আসবে, আমার তুলনাটি এখনও কোনও সংখ্যার number == CardRank.Number(2)চেয়ে একটি নির্দিষ্ট সংখ্যার ( ; যেখানে 2 একটি ডামি মান) এর সাথে তুলনা করার মতো দেখায় ( )।number == CardRank.Number


4
আপনি কমে যায় Jack, Queen, King, Aceমামলার ==: শুধু অপারেটর বাস্তবায়নcase (let x, let y) where x == y: return true
আলেকজান্ডার

উত্তর:


75

সম্পাদনা করুন: ইটান যেমন উল্লেখ করেছে, আপনি (_)এটিকে আরও পরিষ্কারভাবে ব্যবহার করতে ওয়াইল্ডকার্ডের ম্যাচটি বাদ দিতে পারেন।


দুর্ভাগ্যক্রমে, আমি বিশ্বাস করি না যে আপনার switchসুইফট ১.২ এ যাওয়ার চেয়ে সহজ উপায় আছে ।

সুইফট 2-তে, আপনি নতুন if-caseপ্যাটার্ন ম্যাচটি ব্যবহার করতে পারেন :

let number = CardRank.Number(5)
if case .Number(_) = number {
    // Is a number
} else {
    // Something else
}

আপনি যদি ভারবোসিটি এড়ানোর জন্য সন্ধান করছেন, আপনি isNumberআপনার এনামে একটি গণিত সম্পত্তি যুক্ত করার কথা বিবেচনা করতে পারেন যা আপনার সুইচ বিবৃতিটি কার্যকর করে।


4
এটি নিয়ন্ত্রণ প্রবাহের জন্য দুর্দান্ত, তবে যখন আপনি কেবল একটি সরল অভিব্যক্তি চান যেমন:: এটি কৃশ হয় assert(number == .Number)। আমি কেবল আশা করতে পারি এটি সুইফ্টের পরবর্তী সংস্করণগুলিতে উন্নত হয়েছে। = /
জেরেমি

4
লুপ শর্তাদি ইত্যাদির মতো জিনিসগুলির জন্যও স্তন্যপান করে Sw
এটান

ধন্যবাদ @ ইটান, আমি এটি উত্তরে যুক্ত করেছি। আপনি সুইফট 2-এও ওয়াইল্ডকার্ডটি বাদ দিতে পারেন। ভাষাটির বৈশিষ্ট্য প্রকাশের আগে এই উত্তরটি লেখা হয়েছিল, তাই আমি এখনও জানতাম না! :-D
রোনাল্ড মার্টিন

এছাড়াও: যদি কোনও এনামের সাথে সম্পর্কিত মানগুলির সাথে একটি একক কেস থাকে, তবে যদি সেই মানগুলির সাথে সম্পর্কিত মান থাকে না তবে এমনকি যদি সেই ক্ষেত্রে ক্ষেত্রে প্যাটার্ন ব্যবহার করা প্রয়োজন।
এটান

4
@ পিটার ওয়ারবো, আপনি এই প্যাটার্ন-ম্যাচিং সিনট্যাক্সের সাথে প্রত্যাখ্যান করতে পারবেন না। আপাতত আপনাকে defaultএকটি switchব্লকের কোনও মামলায় ফিরে যেতে হবে ।
রোনাল্ড মার্টিন

29

দুর্ভাগ্যক্রমে সুইফট 1.x এ অন্য কোনও উপায় নেই যাতে আপনাকে ব্যবহার করতে হবে switchযা আপনি সুইফট 2 এর সংস্করণ হিসাবে মার্জিত নয় যেখানে আপনি ব্যবহার করতে পারেন if case:

if case .Number = number {
    //ignore the value
}
if case .Number(let x) = number {
    //without ignoring
}

4
দুঃখের বিষয়, এটি শুধুমাত্র ifবিবৃতিতে কাজ করে , একটি অভিব্যক্তি হিসাবে নয়।
রাফেল

20

Equatableআপনার সমস্ত সম্পর্কিত মান সম্মত হলে সুইফটে 4.2 সংশ্লেষিত হবে Equatable। আপনাকে যা করতে হবে তা হ'ল অ্যাড Equatable

enum CardRank: Equatable {
    case Number(Int)
    case Jack
    case Queen
    case King
    case Ace
}

https://developer.apple.com/docamentation/swift/equatable?changes=_3


19
যদিও এটি সম্পর্কিত মানগুলির তুলনা করবে।
জো

3

এখানে একটি সহজ পদ্ধতির:

enum CardRank {
    case Two
    case Three
    case Four
    case Five
    case Six
    case Seven
    case Eight
    case Nine
    case Ten
    case Jack
    case Queen
    case King
    case Ace

    var isFaceCard: Bool {
        return (self == Jack) || (self == Queen) || (self == King)
    }
}

== অপারেটরটি ওভারলোড করার দরকার নেই, এবং কার্ডের ধরণের জন্য পরীক্ষা করতে বিভ্রান্তিকর সিনট্যাক্সের প্রয়োজন নেই:

let card = CardRank.Jack

if card == CardRank.Jack {
    print("You played a jack")
} else if !card.isFaceCard {
    print("You must play a face card!")
}

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

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