কাস্টম ইনিশিয়ালাইজার সহ সুইফট এনাম কাঁচাভালু আরম্ভকারীকে হারায়


96

আমি এই সমস্যাটিকে নীচের সাথে তার সহজতম ফর্মটিতে সিদ্ধ করার চেষ্টা করেছি।

সেটআপ

এক্সকোড সংস্করণ 6.1.1 (6A2008a)

একটি এনাম সংজ্ঞায়িত MyEnum.swift:

internal enum MyEnum: Int {
    case Zero = 0, One, Two
}

extension MyEnum {
    init?(string: String) {
        switch string.lowercaseString {
        case "zero": self = .Zero
        case "one": self = .One
        case "two": self = .Two
        default: return nil
        }
    }
}

এবং কোড যা অন্য ফাইলটিতে এনামকে সূচনা করে MyClass.swift:

internal class MyClass {
    let foo = MyEnum(rawValue: 0)  // Error
    let fooStr = MyEnum(string: "zero")

    func testFunc() {
        let bar = MyEnum(rawValue: 1)  // Error
        let barStr = MyEnum(string: "one")
    }
}

ত্রুটি

এক্সকোডটি MyEnumএর কাঁচা-মান ইনিশিয়ালাইজার দিয়ে আরম্ভ করার চেষ্টা করার সময় আমাকে নিম্নলিখিত ত্রুটি দেয় :

Cannot convert the expression's type '(rawValue: IntegerLiteralConvertible)' to type 'MyEnum?'

মন্তব্য

  1. প্রতি সুইফট ভাষা গাইড :

    আপনি যদি কোনও কাঁচা-মান প্রকারের সাথে একটি গণনা সংজ্ঞায়িত করেন তবে গণনাটি স্বয়ংক্রিয়ভাবে একটি সূচনা প্রাপ্ত হয় যা কাঁচা মানের ধরণের (একটি প্যারামিটার হিসাবে পরিচিত rawValue) একটি মান নেয় এবং হয় একটি গণনা সদস্যকে বা ফেরত দেয় nil

  2. ভাষা নির্দেশিকাMyEnum থেকে নিম্নলিখিত কেসের কারণে এনামের কাঁচা-মান ইনিশিয়ালাইজারটি সরানো হচ্ছে কিনা তা পরীক্ষা করার জন্য কাস্টম ইনিশিয়ালাইজারটি একটি এক্সটেনশনে সংজ্ঞায়িত করা হয়েছিল । তবে এটি একই ত্রুটির ফলাফল অর্জন করে।

    নোট করুন যে আপনি যদি কোনও মান ধরণের জন্য একটি কাস্টম ইনিশিয়ালাইজারটি সংজ্ঞায়িত করেন তবে সেই ধরণের জন্য আপনার আর ডিফল্ট আরম্ভকারী (বা সদস্যবিহীন প্রাথমিককরণ, যদি এটি কাঠামো হয়) অ্যাক্সেস পাবেন না। [...]
    আপনি যদি নিজের কাস্টম মান প্রকারটি ডিফল্ট আরম্ভকারী এবং সদস্যবিহীন আরম্ভকারী এবং আপনার নিজস্ব কাস্টম ইনিশিয়েলাইজারের সাথে আরম্ভ করতে সক্ষম হন তবে মান প্রকারের আসল বাস্তবায়নের অংশ হিসাবে পরিবর্তে নিজের কাস্টম আরম্ভকারীকে লিখুন।

  3. Enum সংজ্ঞা মুভিং করার MyClass.swiftজন্য ত্রুটি সমাধান করা barকিন্তু না করার জন্য foo

  4. কাস্টম ইনিশিয়ালাইজার সরানো উভয় ত্রুটি সমাধান করে।

  5. একটি কর্মসূচী হ'ল এনাম সংজ্ঞাতে নিম্নলিখিত ফাংশনটি অন্তর্ভুক্ত করা এবং এটি সরবরাহ করা কাঁচা-মান প্রাথমিককরণের জায়গায় ব্যবহার করা। সুতরাং দেখে মনে হচ্ছে যেন কাস্টম ইনিশিয়ালাইজার যুক্ত করা কাঁচা-মান শুরুর দিকে চিহ্নিত করার অনুরূপ প্রভাব ফেলে private

    init?(raw: Int) {
        self.init(rawValue: raw)
    }
    
  6. স্পষ্টভাবে করতে প্রোটোকল অনুরূপ ঘোষণা RawRepresentableমধ্যে MyClass.swiftজন্য ইনলাইন ত্রুটি সমাধান করা bar, কিন্তু ডুপ্লিকেট প্রতীক সম্পর্কে একটি linker ভুলবশত ফলাফল (কারণ কাঁচা-মান টাইপ enums পরোক্ষভাবে সাথে সামঞ্জস্য RawRepresentable)।

    extension MyEnum: RawRepresentable {}
    

এখানে কী চলছে সে সম্পর্কে কি কেউ আরও কিছুটা অন্তর্দৃষ্টি দিতে পারেন? কাঁচা-মান প্রাথমিককরণ অ্যাক্সেসযোগ্য নয় কেন?


আপনার এটিতে একটি বাগ ফাইল করা উচিত - ডিফল্ট ইনিশিয়েলাইজারদের internalস্কোপ থাকতে হবে (বা কমপক্ষে টাইপের সাথে মিল রয়েছে), তা নয় private
নাট কুক

আমার ঠিক একই সমস্যা হচ্ছে আমি একবার কাস্টম ইনিশিয়ালাইজার তৈরি করলে ডিফল্টটি চলে যায়
ইয়ারিভ নিসিম

আমার কাছে বাগের মতো গন্ধ পেয়েছে।
আকাশীবস্কিয়

4
আমার সন্দেহগুলি বৈধ করার জন্য ধন্যবাদ এটি বাগ হিসাবে দায়ের করা হয়েছে।
নিকগ্রাফ

5 নম্বরটি আমার জন্য এটি করেছিল did
অ্যান্ড্রু ডানকান

উত্তর:


26

এই বাগটি এক্সকোড 7 এবং সুইফ্ট 2 এ সমাধান করা হয়েছে


25
সম্পর্কিত টিকিটের লিঙ্ক থেকে এই জাতীয় লাভের উত্তরগুলি যাতে ভবিষ্যতের দর্শকরা বিষয়টির অবস্থাটি পরীক্ষা করতে পারেন।
রাফেল

14
extension TemplateSlotType {
    init?(rawString: String) {
        // Check if string contains 'carrousel'
        if rawString.rangeOfString("carrousel") != nil {
            self.init(rawValue:"carrousel")
        } else {
            self.init(rawValue:rawString)
        }
    }
}

আপনার ক্ষেত্রে এটি নিম্নলিখিত এক্সটেনশনের ফলাফল করবে:

extension MyEnum {
    init?(string: String) {
        switch string.lowercaseString {
        case "zero": 
            self.init(rawValue:0)
        case "one": 
            self.init(rawValue:1)
        case "two":
            self.init(rawValue:2)
        default: 
            return nil
        }
    }
}

7

আপনি কোডগুলি switchকেস ছাড়াই আরও সহজ এবং দরকারী করে তুলতে পারেন , আপনি যখন নতুন ধরণের যুক্ত করেন তখন আপনাকে আরও কেস যুক্ত করার প্রয়োজন হয় না।

enum VehicleType: Int, CustomStringConvertible {
    case car = 4
    case moped = 2
    case truck = 16
    case unknown = -1

    // MARK: - Helpers

    public var description: String {
        switch self {
        case .car: return "Car"
        case .truck: return "Truck"
        case .moped: return "Moped"
        case .unknown: return "unknown"
        }
    }

    static let all: [VehicleType] = [car, moped, truck]

    init?(rawDescription: String) {
        guard let type = VehicleType.all.first(where: { description == rawDescription })
            else { return nil }
        self = type
    }
}

1

হ্যাঁ এটি একটি বিরক্তিকর বিষয়। আমি বর্তমানে এটি বিশ্বব্যাপী স্কোপ ফাংশন ব্যবহার করে এর চারপাশে কাজ করছি যা কারখানা হিসাবে কাজ করে, যেমন

func enumFromString(string:String) -> MyEnum? {
    switch string {
    case "One" : MyEnum(rawValue:1)
    case "Two" : MyEnum(rawValue:2)
    case "Three" : MyEnum(rawValue:3)
    default : return nil
    }
}

1

এটি আমার এনামসিকিউয়েন্সের সাথে এক্সকোড 9.2 এ সুইফট 4-এর জন্য কাজ করে :

enum Word: Int, EnumSequenceElement, CustomStringConvertible {
    case apple, cat, fun

    var description: String {
        switch self {
        case .apple:
            return "Apple"
        case .cat:
            return "Cat"
        case .fun:
            return "Fun"
        }
    }
}

let Words: [String: Word] = [
    "A": .apple,
    "C": .cat,
    "F": .fun
]

extension Word {
    var letter: String? {
        return Words.first(where: { (_, word) -> Bool in
            word == self
        })?.key
    }

    init?(_ letter: String) {
        if let word = Words[letter] {
            self = word
        } else {
            return nil
        }
    }
}

for word in EnumSequence<Word>() {
    if let letter = word.letter, let lhs = Word(letter), let rhs = Word(letter), lhs == rhs {
        print("\(letter) for \(word)")
    }
}

আউটপুট

A for Apple
C for Cat
F for Fun

-1

এটি আপনার কোডে যুক্ত করুন:

extension MyEnum {
    init?(rawValue: Int) {
        switch rawValue {
        case 0: self = .Zero
        case 1: self = .One
        case 2: self = .Two
        default: return nil
        }
    }
}

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