ios - কিভাবে সুইফ্টে NS_OPTIONS- শৈলী বিটমাস্ক বুদ্ধিমত্তা তৈরি করবেন?



bitwise-operators swift (10)

সি এপিআইগুলির সাথে ইন্টারঅ্যাক্ট করার বিষয়ে অ্যাপল এর ডকুমেন্টেশনে, তারা NS_ENUM চিহ্নিত C-শৈলী সংখ্যার NS_ENUM এনমারেশনস হিসাবে আমদানি করা হয় NS_ENUM বর্ণনা করে। এটি ইন্দ্রিয় তোলে, এবং সুইফ্টের পরিসংখ্যানগুলি সহজেই enum মানের ধরন হিসাবে সরবরাহ করা হয়, এটি আমাদের নিজের তৈরি করা যায় তা দেখতে সহজ।

আরও নিচে, এটি NS_OPTIONS চিহ্নিত C-শৈলী বিকল্পগুলির সম্পর্কে এটি বলে:

NS_OPTIONS ম্যাক্রোর সাথে চিহ্নিত বিকল্পগুলি আমদানি করে। যেখানে বিকল্পগুলি আমদানি করা সংখ্যার অনুরূপ আচরণ করে, বিকল্পগুলি কিছু বিটwise ক্রিয়াকলাপকে সমর্থন করে, যেমন & , | , এবং ~ । Objective-C তে, আপনি নিখুঁত শূন্য ( 0 ) সহ একটি খালি বিকল্পটি উপস্থাপন করেন। সুইফ্টে, যেকোনো বিকল্পের অভাবে প্রতিনিধিত্ব করতে nil ব্যবহার করুন।

সুইফ্টে একটি options মান টাইপ নেই বলে দেওয়া হয়েছে, আমরা কিভাবে কাজ করতে সি-স্টাইল বিকল্পের পরিবর্তনশীল তৈরি করতে পারি?


Answer #1

সুইফ্ট 3.0

সুইফ্ট 2.0 প্রায় অভিন্ন। অপশনসেট টাইপকে বিকল্পসেটে নামকরণ করা হয়েছিল এবং কনফারেন্সের মাধ্যমে ছোটখাটো লেখা লিখেছেন।

struct MyOptions : OptionSet {
    let rawValue: Int

    static let firstOption  = MyOptions(rawValue: 1 << 0)
    static let secondOption = MyOptions(rawValue: 1 << 1)
    static let thirdOption  = MyOptions(rawValue: 1 << 2)
}

none বিকল্প সরবরাহ করার পরিবর্তে, সুইফ্ট 3 সুপারিশটি কেবল খালি অ্যারের আক্ষরিক ব্যবহার করা হয়:

let noOptions: MyOptions = []

অন্যান্য ব্যবহার:

let singleOption = MyOptions.firstOption
let multipleOptions: MyOptions = [.firstOption, .secondOption]
if multipleOptions.contains(.secondOption) {
    print("multipleOptions has SecondOption")
}
let allOptions = MyOptions(rawValue: 7)
if allOptions.contains(.thirdOption) {
    print("allOptions has ThirdOption")
}

সুইফ্ট 2.0

সুইফ্ট 2.0 এ, প্রোটোকল এক্সটেনশানগুলি এইগুলির জন্য বয়লারপ্লেটের বেশিরভাগের যত্ন নেয়, যা বর্তমানে OptionSetType সাথে একটি OptionSetType মতো আমদানি করা হয়। ( RawOptionSetType সুইফ্ট 2 বিটা 2 হিসাবে অদৃশ্য হয়ে গেছে।) ঘোষণাটি অনেক সহজ:

struct MyOptions : OptionSetType {
    let rawValue: Int

    static let None         = MyOptions(rawValue: 0)
    static let FirstOption  = MyOptions(rawValue: 1 << 0)
    static let SecondOption = MyOptions(rawValue: 1 << 1)
    static let ThirdOption  = MyOptions(rawValue: 1 << 2)
}

এখন আমরা MyOptions সাহায্যে সেট-ভিত্তিক MyOptions ব্যবহার করতে MyOptions :

let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = [.FirstOption, .SecondOption]
if multipleOptions.contains(.SecondOption) {
    print("multipleOptions has SecondOption")
}
let allOptions = MyOptions(rawValue: 7)
if allOptions.contains(.ThirdOption) {
    print("allOptions has ThirdOption")
}

সুইফ্ট 1.2

সুইফ্ট ( UIViewAutoresizing , উদাহরণস্বরূপ, উদাহরণস্বরূপ) দ্বারা আমদানি করা উদ্দেশ্য-সি বিকল্পগুলির দিকে তাকিয়ে আমরা দেখতে পাচ্ছি যে বিকল্পগুলি RawOptionSetType হিসাবে ঘোষিত হয় যা RawOptionSetType প্রোটোকলের সাথে RawOptionSetType , যা পরিবর্তে _RawOptionSetType , Equatable , RawRepresentable , BitwiseOperationsType এবং NilLiteralConvertible । আমরা এই মত আমাদের নিজস্ব তৈরি করতে পারেন:

struct MyOptions : RawOptionSetType {
    typealias RawValue = UInt
    private var value: UInt = 0
    init(_ value: UInt) { self.value = value }
    init(rawValue value: UInt) { self.value = value }
    init(nilLiteral: ()) { self.value = 0 }
    static var allZeros: MyOptions { return self(0) }
    static func fromMask(raw: UInt) -> MyOptions { return self(raw) }
    var rawValue: UInt { return self.value }

    static var None: MyOptions { return self(0) }
    static var FirstOption: MyOptions   { return self(1 << 0) }
    static var SecondOption: MyOptions  { return self(1 << 1) }
    static var ThirdOption: MyOptions   { return self(1 << 2) }
}

এখন আমরা এই নতুন বিকল্প সেটটি ব্যবহার করতে পারি, MyOptions , ঠিক যেমন অ্যাপল এর ডকুমেন্টেশনে বর্ণনা করা হয়েছে: আপনি MyOptions like সিনট্যাক্স ব্যবহার করতে পারেন:

let opt1 = MyOptions.FirstOption
let opt2: MyOptions = .SecondOption
let opt3 = MyOptions(4)

এবং এটি আচরণ করে যেমন আমরা বিকল্পগুলি ব্যবহার করার আশা করি:

let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = singleOption | .SecondOption
if multipleOptions & .SecondOption != nil {     // see note
    println("multipleOptions has SecondOption")
}
let allOptions = MyOptions.fromMask(7)   // aka .fromMask(0b111)
if allOptions & .ThirdOption != nil {
    println("allOptions has ThirdOption")
}

আমি সব খুঁজে / প্রতিস্থাপন ছাড়া একটি সুইফট অপশন সেট তৈরি করতে একটি জেনারেটর নির্মিত করেছি।

সর্বশেষ: সুইট 1.1 বিটা 3 এর জন্য পরিবর্তন।


Answer #2

অন্য কেউ এটি উল্লেখ করেনি - এবং আমি কিছু tinkering পরে এটি সম্মুখের blundered - কিন্তু একটি সুইফট সেট মোটামুটি ভাল কাজ বলে মনে হয়।

যদি আমরা মনে করি (সম্ভবত একটি ভেন ডায়াগ্রামে?) আসলে কি একটি বিট মাস্ক প্রতিনিধিত্ব করে, এটি সম্ভবত একটি খালি সেট।

অবশ্যই, প্রথম নীতিগুলি থেকে সমস্যার দিকে এগিয়ে যাওয়ার সময়, আমরা বিটওয়াই অপারেটরদের সুবিধাটি হারাতে পারি, কিন্তু শক্তিশালী সেট ভিত্তিক পদ্ধতিগুলি পঠনযোগ্যতা উন্নত করে।

এখানে উদাহরণস্বরূপ আমার tinkering হয়:

enum Toppings : String {
    // Just strings 'cause there's no other way to get the raw name that I know of...
    // Could be 1 << x too...
    case Tomato = "tomato"
    case Salami = "salami"
    case Cheese = "cheese"
    case Chicken = "chicken"
    case Beef = "beef"
    case Anchovies = "anchovies"

    static let AllOptions: Set<Toppings> = [.Tomato, .Salami, .Cheese, .Chicken, .Anchovies, .Beef]
}

func checkPizza(toppings: Set<Toppings>) {
    if toppings.contains(.Cheese) {
        print("Possible dairy allergies?")
    }

    let meats: Set<Toppings> = [.Beef, .Chicken, .Salami]
    if toppings.isDisjointWith(meats) {
        print("Vego-safe!")
    }
    if toppings.intersect(meats).count > 1 {
        print("Limit one meat, or 50¢ extra charge!")
    }

    if toppings == [Toppings.Cheese] {
        print("A bit boring?")
    }
}

checkPizza([.Tomato, .Cheese, .Chicken, .Beef])

checkPizza([.Cheese])

আমি এই সুন্দরটি খুঁজে পেয়েছি কারণ আমি মনে করি সি-স্টাইল সমাধানগুলি মানিয়ে নেওয়ার চেষ্টা করার পরিবর্তে - এটি সুইফ্টের মতো - সমস্যার প্রথম দিক থেকে আসে।

কিছু Obj-C ব্যবহার ক্ষেত্রেও শুনতে চান যা এই ভিন্ন প্যারাডিজমটিকে চ্যালেঞ্জ করবে, যেখানে পূর্ণসংখ্যা কাঁচা মানগুলি এখনও মেধার দেখায়।


Answer #3

আমি নিম্নলিখিত ব্যবহার করি আমি পেতে পারেন উভয় মান, আমি indexing অ্যারে এবং পতাকা জন্য মান জন্য rawValue প্রয়োজন।

enum MyEnum: Int {
    case one
    case two
    case four
    case eight

    var value: UInt8 {
        return UInt8(1 << self.rawValue)
    }
}

let flags: UInt8 = MyEnum.one.value ^ MyEnum.eight.value

(flags & MyEnum.eight.value) > 0 // true
(flags & MyEnum.four.value) > 0  // false
(flags & MyEnum.two.value) > 0   // false
(flags & MyEnum.one.value) > 0   // true

MyEnum.eight.rawValue // 3
MyEnum.four.rawValue  // 2

এবং যদি আরো একটি প্রয়োজন শুধু একটি গণিত সম্পত্তি যোগ করুন।

enum MyEnum: Int {
    case one
    case two
    case four
    case eight

    var value: UInt8 {
        return UInt8(1 << self.rawValue)
    }

    var string: String {
        switch self {
        case .one:
            return "one"
        case .two:
            return "two"
        case .four:
            return "four"
        case .eight:
            return "eight"
        }
    }
}

Answer #4

এক্সকোড 6.1 বিটা 2 RawOptionSetType প্রোটোকলে কিছু পরিবর্তন আনা হয়েছে (এই এয়ারস্পাইডভেলসটি ব্লগ এন্ট্রি এবং অ্যাপল রিলিজ নোট দেখুন )।

এখানে নাইট কুক উদাহরণস্বরূপ একটি আপডেট সমাধান হয়। আপনি নিজের মত সেট বিকল্পটি সংজ্ঞায়িত করতে পারেন:

struct MyOptions : RawOptionSetType, BooleanType {
    private var value: UInt
    init(_ rawValue: UInt) { self.value = rawValue }

    // MARK: _RawOptionSetType
    init(rawValue: UInt) { self.value = rawValue }

    // MARK: NilLiteralConvertible
    init(nilLiteral: ()) { self.value = 0}

    // MARK: RawRepresentable
    var rawValue: UInt { return self.value }

    // MARK: BooleanType
    var boolValue: Bool { return self.value != 0 }

    // MARK: BitwiseOperationsType
    static var allZeros: MyOptions { return self(0) }

    // MARK: User defined bit values
    static var None: MyOptions          { return self(0) }
    static var FirstOption: MyOptions   { return self(1 << 0) }
    static var SecondOption: MyOptions  { return self(1 << 1) }
    static var ThirdOption: MyOptions   { return self(1 << 2) }
    static var All: MyOptions           { return self(0b111) }
}

তারপরে ভেরিয়েবলগুলিকে সংজ্ঞায়িত করতে এরকম ব্যবহার করা যেতে পারে:

let opt1 = MyOptions.FirstOption
let opt2:MyOptions = .SecondOption
let opt3 = MyOptions(4)

এবং বিট জন্য পরীক্ষা করার মত এই:

let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = singleOption | .SecondOption
if multipleOptions & .SecondOption {
    println("multipleOptions has SecondOption")
}

let allOptions = MyOptions.All
if allOptions & .ThirdOption {
    println("allOptions has ThirdOption")
}

Answer #5

দ্রুত ব্যবহার 3 বিকল্প OptionSet মধ্যে একটি বিকল্প সেট প্রকার ব্যবহার OptionSet

struct ShippingOptions: OptionSet {
    let rawValue: Int

    static let nextDay    = ShippingOptions(rawValue: 1 << 0)
    static let secondDay  = ShippingOptions(rawValue: 1 << 1)
    static let priority   = ShippingOptions(rawValue: 1 << 2)
    static let standard   = ShippingOptions(rawValue: 1 << 3)

    static let express: ShippingOptions = [.nextDay, .secondDay]
    static let all: ShippingOptions = [.express, .priority, .standard]
}

Answer #6

পুনরায়: বিভিন্ন অপশন দিয়ে বিকল্প সেট ব্যবহার করে স্যান্ডবক্স এবং বুকমার্ক সৃষ্টি

let options:NSURL.BookmarkCreationOptions = [.withSecurityScope,.securityScopeAllowOnlyReadAccess]
let temp = try link.bookmarkData(options: options, includingResourceValuesForKeys: nil, relativeTo: nil)

সৃষ্টির জন্য বিকল্পগুলি একত্র করার প্রয়োজন সমাধান, সমস্ত বিকল্প পারস্পরিক একচেটিয়া নয় যখন দরকারী।


Answer #7

যদি আমাদের প্রয়োজন হয় তবে একমাত্র কার্যকারিতা বিকল্পগুলির সাথে একত্রিত করার উপায় এবং সংযুক্ত বিকল্পগুলির সাথে একটি বিশেষ বিকল্প রয়েছে কিনা তা পরীক্ষা করুন এবং নেট কুকের উত্তরের বিকল্পটি এই হতে পারে:

একটি বিকল্প protocol এবং ওভারলোড তৈরি করুন এবং &

protocol OptionsProtocol {

    var value: UInt { get }
    init (_ value: UInt)

}

func | <T: OptionsProtocol>(left: T, right: T) -> T {
    return T(left.value | right.value)
}

func & <T: OptionsProtocol>(left: T, right: T) -> Bool {
    if right.value == 0 {
        return left.value == 0
    }
    else {
        return left.value & right.value == right.value
    }
}

এখন আমরা আরো সহজভাবে বিকল্প structs তৈরি করতে পারেন:

struct MyOptions: OptionsProtocol {

    private(set) var value: UInt
    init (_ val: UInt) {value = val}

    static var None: MyOptions { return self(0) }
    static var One: MyOptions { return self(1 << 0) }
    static var Two: MyOptions { return self(1 << 1) }
    static var Three: MyOptions { return self(1 << 2) }
}

তারা নিম্নরূপ ব্যবহার করা যেতে পারে:

func myMethod(#options: MyOptions) {
    if options & .One {
        // Do something
    }
}

myMethod(options: .One | .Three) 

Answer #8

রিকস্টার ইতিমধ্যে উল্লেখ করেছেন, আপনি সুইফ্ট 2.0 এ OptionSetType ব্যবহার করতে পারেন। অপশনটি সেট OptionSetType প্রোটোকল অনুসারে কনফিগার করার মতো NS_OPTIONS প্রকারগুলি আমদানি করে, যা বিকল্পগুলির জন্য সেট-সেট ইন্টারফেস উপস্থাপন করে:

struct CoffeeManipulators : OptionSetType {
    let rawValue: Int
    static let Milk     = CoffeeManipulators(rawValue: 1)
    static let Sugar    = CoffeeManipulators(rawValue: 2)
    static let MilkAndSugar = [Milk, Sugar]
}

এটি আপনাকে কাজ করার এই পদ্ধতি দেয়:

struct Coffee {
    let manipulators:[CoffeeManipulators]

    // You can now simply check if an option is used with contains
    func hasMilk() -> Bool {
        return manipulators.contains(.Milk)
    }

    func hasManipulators() -> Bool {
        return manipulators.count != 0
    }
}

Answer #9

(1 << 0) , (1 << 1) , (1 << 15) ইত্যাদি বা আরও খারাপ 1 , 2 , 16384 ইত্যাদি ব্যবহার করে বা কিছু হেক্সাডেসিমাল ব্যবহার করার সময় বিট পজিশনগুলিকে হার্ড কোডিং এড়ানোর জন্য, যা অপরিহার্য। বৈচিত্র্য, প্রথম কেউ একটি enum মধ্যে বিট সংজ্ঞায়িত করতে পারে, তারপর Enum বিট অর্ডিনাল গণনা করবেন বলে দিন:

// Bits
enum Options : UInt {
    case firstOption
    case secondOption
    case thirdOption
}

// Byte
struct MyOptions : OptionSet {
    let rawValue: UInt

    static let firstOption  = MyOptions(rawValue: 1 << Options.firstOption.rawValue)
    static let secondOption = MyOptions(rawValue: 1 << Options.secondOption.rawValue)
    static let thirdOption  = MyOptions(rawValue: 1 << Options.thirdOption.rawValue)
}

Answer #10

নাট এর উত্তর ভাল কিন্তু আমি নিজেও এটি তৈরি করব, যেমন:

struct MyOptions : OptionSetType {
    let rawValue: Int

    static let None         = Element(rawValue: 0)
    static let FirstOption  = Element(rawValue: 1 << 0)
    static let SecondOption = Element(rawValue: 1 << 1)
    static let ThirdOption  = Element(rawValue: 1 << 2)
}




swift