সুইফট সুইচ স্টেটমেন্টের চেয়ে কম বা বেশি


145

আমি switchসুইফটে বিবৃতিগুলির সাথে পরিচিত , তবে কীভাবে এই কোডের এই টুকরোটি প্রতিস্থাপন করব তা অবাক করে switch:

if someVar < 0 {
    // do something
} else if someVar == 0 {
    // do something else
} else if someVar > 0 {
    // etc
}

যদিও এটি একটি আকর্ষণীয় প্রশ্ন, আমি মনে করি সুইচ ব্যবহার করে কোডটি যদি বিবৃতিগুলির চেয়ে কম কম পঠনযোগ্য হয়। আপনি পারছেন বলে কেবল তার মানে নয়।
রগ

উত্তর:


241

এখানে একটি পদ্ধতির। ধরে someVarনেওয়া একটি Intবা অন্য Comparable, আপনি বিকল্পভাবে একটি নতুন ভেরিয়েবলের জন্য অপারেন্ড নির্ধারণ করতে পারেন। আপনি whereকীওয়ার্ডটি ব্যবহার করতে চাইলেও এটি আপনাকে এটির সুযোগ দেয় :

var someVar = 3

switch someVar {
case let x where x < 0:
    print("x is \(x)")
case let x where x == 0:
    print("x is \(x)")
case let x where x > 0:
    print("x is \(x)")
default:
    print("this is impossible")
}

এটি কিছুটা সহজ করা যায়:

switch someVar {
case _ where someVar < 0:
    print("someVar is \(someVar)")
case 0:
    print("someVar is 0")
case _ where someVar > 0:
    print("someVar is \(someVar)")
default:
    print("this is impossible")
}

আপনি whereপরিসীমা ম্যাচিংয়ের সাথে কীওয়ার্ডটি পুরোপুরি এড়াতে পারেন :

switch someVar {
case Int.min..<0:
    print("someVar is \(someVar)")
case 0:
    print("someVar is 0")
default:
    print("someVar is \(someVar)")
}

9
আমি default: fatalError()সম্ভাব্য লজিক ত্রুটিগুলি দ্রুত সনাক্ত করার পরামর্শ দিই ।
মার্টিন আর

1
ধন্যবাদ! এই উদাহরণগুলি খুব সহায়ক এবং তারা আমার সমস্যা সমাধান করে! (অন্যান্য উদাহরণগুলিও ভাল ছিল তবে আপনার জন্য আমার পক্ষে সবচেয়ে সহায়ক ছিল)
পিটার

1
@ মার্টিনআর assertionFailureএকটি নিরাপদ বিকল্প বলে মনে হচ্ছে, বিশেষত দলে কাজ করার সময়।
মাইকেল ভোলাইন

119

সুইফট 5 এর সাহায্যে, আপনার যদি বিবৃতিটি প্রতিস্থাপন করতে আপনি নীচের একটি স্যুইচ চয়ন করতে পারেন।


# 1 PartialRangeFromএবং সাথে স্যুইচ ব্যবহার করে UsingPartialRangeUpTo

let value = 1

switch value {
case 1...:
    print("greater than zero")
case 0:
    print("zero")
case ..<0:
    print("less than zero")
default:
    fatalError()
}

# 2 ClosedRangeএবং সাথে স্যুইচ ব্যবহার করেRange

let value = 1

switch value {
case 1 ... Int.max:
    print("greater than zero")
case Int.min ..< 0:
    print("less than zero")
case 0:
    print("zero")
default:
    fatalError()
}

# 3 যেখানে ক্লজ সহ স্যুইচ ব্যবহার করে

let value = 1

switch value {
case let val where val > 0:
    print("\(val) is greater than zero")
case let val where val == 0:
    print("\(val) is zero")
case let val where val < 0:
    print("\(val) is less than zero")
default:
    fatalError()
}

# 4 যেখানে ক্লজ এবং অ্যাসাইনমেন্ট সহ স্যুইচ ব্যবহার করে _

let value = 1

switch value {
case _ where value > 0:
    print("greater than zero")
case _ where value == 0:
    print("zero")
case _ where value < 0:
    print("less than zero")
default:
    fatalError()
}

# 5 RangeExpressionপ্রোটোকলের ~=(_:_:)অপারেটরের সাথে স্যুইচ ব্যবহার করা

let value = 1

switch true {
case 1... ~= value:
    print("greater than zero")
case ..<0 ~= value:
    print("less than zero")
default:
    print("zero")
}

# 6 Equatableপ্রোটোকলের ~=(_:_:)অপারেটরের সাথে স্যুইচ ব্যবহার করা

let value = 1

switch true {
case value > 0:
    print("greater than zero")
case value < 0:
    print("less than zero")
case 0 ~= value:
    print("zero")
default:
    fatalError()
}

# 7 স্যুইচ সহ PartialRangeFrom, PartialRangeUpToএবং RangeExpressionএর contains(_:)পদ্ধতি ব্যবহার করে

let value = 1

switch true {
case (1...).contains(value):
    print("greater than zero")
case (..<0).contains(value):
    print("less than zero")
default:
    print("zero")
}

1
# 2 এ ডিফল্ট মামলাটি কেন প্রয়োজন? ভাসা মনে হচ্ছে যে যদি রেঞ্জটি ইন্ট.মিন থেকে ইন্টার.ম্যাক্সে থাকে তবে কী বাকি?
λαβέ.λαβέ

বাহ, অপশনগুলির দুর্দান্ত তালিকা। এটি করার বিভিন্ন উপায় রয়েছে তা জেনে রাখা ভাল।
ক্রিস্টোফার পিক্সলে

2
ভাল ওভারভিউ কিন্তু ত্রুটিযুক্ত কারণ 0 এবং 1 এর মধ্যে সংখ্যাগুলি অনাবৃত। 0.1একটি মারাত্মক ত্রুটি ছোঁড়া কারণ 1...কভার শুধুমাত্র 1. থেকে নম্বর সুতরাং এই সমাধান শুধুমাত্র যদি কাজ করে valueএকটি হল Intকিন্তু যে বিপজ্জনক পরিবর্তনশীল টাইপ কোনো কম্পাইলার ত্রুটি ছাড়া কার্যকারিতা বিরতি পরিবর্তন যদি কারণ।
ম্যানুয়েল

1
আপনার সমাধান ডাবল টাইপের জন্য সঠিকভাবে কাজ করে না। কেস 1 ...: মুদ্রণ ( "শূন্য তার চেয়ে অনেক বেশী") 0 থেকে বেশি না বেশী বা 1. সমান
Vlad

20

switchবিবৃতি, অধীন ফণা, ব্যবহার ~=অপারেটর। আমার স্নাতকের:

let x = 2

switch x {
case 1: print(1)
case 2: print(2)
case 3..<5: print(3..<5)
default: break
}

এটির জন্য ডিজুগার:

if 1          ~= x { print(1) }
else if 2     ~= x { print(2) }
else if 3..<5 ~= x { print(3..<5) }
else {  }

আপনি যদি স্ট্যান্ডার্ড লাইব্রেরি রেফারেন্সের দিকে তাকান তবে এটি আপনাকে কী করতে হবে তা ঠিক বলতে ~=পারে : অন্তর্ভুক্তটি হ'ল পরিসীমা-মেলা এবং সমতুল্য জিনিসগুলির জন্য সমান equ (অন্তর্ভুক্ত নয় এনাম-কেস ম্যাচিং, যা একটি ভাষা বৈশিষ্ট্য, স্টাড লিবিবের কোনও ফাংশনের চেয়ে)

আপনি দেখতে পাবেন যে এটি বাম-পাশের কোনও সোজা বুলেটিনের সাথে মেলে না। এই ধরণের তুলনার জন্য আপনার একটি বিবৃতি যুক্ত করতে হবে।

যদি না ... আপনি ~=নিজে অপারেটরটি ওভারলোড করেন । (এটি সাধারণত প্রস্তাবিত নয় ) একটি সম্ভাবনা হ'ল এরকম কিছু হবে:

func ~= <T> (lhs: T -> Bool, rhs: T) -> Bool {
  return lhs(rhs)
}

সুতরাং এটি এমন কোনও ফাংশনটির সাথে মেলে যা ডানদিকে তার প্যারামিটারে বামদিকে একটি বুলিয়ান দেয়। আপনি যে ধরণের জিনিসটির জন্য এটি ব্যবহার করতে পারেন তা এখানে:

func isEven(n: Int) -> Bool { return n % 2 == 0 }

switch 2 {
case isEven: print("Even!")
default:     print("Odd!")
}

আপনার ক্ষেত্রে, আপনার কাছে এমন একটি বিবৃতি থাকতে পারে যা দেখতে এটির মতো দেখাচ্ছে:

switch someVar {
case isNegative: ...
case 0: ...
case isPositive: ...
}

তবে এখন আপনাকে নতুন isNegativeএবং isPositiveকার্যকারিতা সংজ্ঞায়িত করতে হবে । আপনি যদি কিছু অপারেটরকে ওভারলোড না করেন ...

আপনি সাধারণ ইনফিক্স অপারেটরগুলিকে তরকারী উপসর্গ বা পোস্টফিক্স অপারেটরগুলি ওভারলোড করতে পারেন। এখানে একটি উদাহরণ:

postfix operator < {}

postfix func < <T : Comparable>(lhs: T)(_ rhs: T) -> Bool {
  return lhs < rhs
}

এটি এর মতো কাজ করবে:

let isGreaterThanFive = 5<

isGreaterThanFive(6) // true
isGreaterThanFive(5) // false

পূর্ববর্তী ফাংশনটির সাথে এটি একত্রিত করুন এবং আপনার সুইচ স্টেটমেন্টটি দেখতে দেখতে এটি দেখতে পারে:

switch someVar {
case 0< : print("Bigger than 0")
case 0  : print("0")
default : print("Less than 0")
}

এখন, আপনার সম্ভবত অনুশীলনে এই ধরণের জিনিস ব্যবহার করা উচিত নয়: এটি কিছুটা দোষজনক। আপনি (সম্ভবত) বয়ানটি স্টিকিংয়ের চেয়ে ভাল where। যা বলেছিল, এর স্যুইচ স্টেটমেন্ট প্যাটার্ন

switch x {
case negative:
case 0:
case positive:
}

অথবা

switch x {
case lessThan(someNumber):
case someNumber:
case greaterThan(someNumber):
}

এটি বিবেচনা করার মতো বলে মনে হচ্ছে এটি যথেষ্ট সাধারণ।


1
আপনার প্রশ্নের উত্তর কোথায়? আমি এটি খুঁজে পাচ্ছি না।
মধু

1
কেস 3 .. <5: মুদ্রণ (3 .. <5) - আক্ষরিক অর্থে প্রথম অনুচ্ছেদে। এই উত্তর আন্ডাররেটেড হয়। আমাকে এত কোড বাঁচায়
করিম

14

আপনি পারেন:

switch true {
case someVar < 0:
    print("less than zero")
case someVar == 0:
    print("eq 0")
default:
    print("otherwise")
}

6

যেহেতু কেউ ইতিমধ্যেই পোস্ট করেছে case let x where x < 0:এখানে যেখানে একটি বিকল্প নেই someVarএকটি হল Int

switch someVar{
case Int.min...0: // do something
case 0: // do something
default: // do something
}

এবং এখানে যেখানে একটি বিকল্প নেই someVarএকটি হল Double:

case -(Double.infinity)...0: // do something
// etc

6

রেঞ্জগুলির সাথে এটি দেখতে কেমন লাগে

switch average {
case 0..<40: //greater or equal than 0 and less than 40
    return "T"
case 40..<55: //greater or equal than 40 and less than 55
    return "D"
case 55..<70: //greater or equal than 55 and less than 70
    return "P"
case 70..<80: //greater or equal than 70 and less than 80
    return "A"
case 80..<90: //greater or equal than 80 and less than 90
    return "E"
case 90...100: //greater or equal than 90 and less or equal than 100
    return "O"
default:
    return "Z"
}

3

<0অভিব্যক্তি (আর?) কাজ করে না তাই আমি এই সঙ্গে শেষ পর্যন্ত:

সুইফট 3.0:

switch someVar {
    case 0:
        // it's zero
    case 0 ..< .greatestFiniteMagnitude:
        // it's greater than zero
    default:
        // it's less than zero
    }

1
দ্রুতগতি 3.0-এর ক্ষেত্রে X_MAXদ্বারা প্রতিস্থাপিত হয়েছে .greatestFiniteMagnitude, অর্থাত্ Double.greatestFiniteMagnitude, CGFloat.greatestFiniteMagnitudeইত্যাদি সুতরাং সাধারণত, আপনি শুধু করতে পারি না case 0..< .greatestFiniteMagnitudeধরণ থেকে someVarইতিমধ্যে পরিচিত হয়
Guig

@ দরিয়ান রায় অপারেটরটি var timeLeft = 100 switch timeLeft {case 0...<=7200: print("ok") default:print("nothing") }কেন <=স্বীকৃত নয়? আমি যদি এটি সমান না করে লিখি তবে এটি কাজ করে। ধন্যবাদ
বাইবিসি

@ বিবিসি আপনি বদ্ধ রেঞ্জ অপারেটরটি ব্যবহার করতে চান: case 0...7200:অপারেটর <=একটি তুলনামূলক অপারেটর। একটি স্যুইচে আপনি কেবল ব্যাপ্তি অপারেটর ব্যবহার করতে পারেন (দস্তাবেজগুলি দেখুন)
ডোরিয়ান রায়

এই দুর্দান্ত ছিল। আমি 'রেঞ্জ <ডাবল>' টাইপের এই ত্রুটি প্রকাশের প্যাটার্নটি পেয়ে যাচ্ছিলাম 'ইন্টার' টাইপের মানগুলির সাথে মেলে না কারণ এটি আমার someVarছিল Intএবং আমাকে Double(কিছুটা করতে হয়েছিল)
হানি

2

খুশি যে সুইফট 4 সমস্যাটির সমাধান করে:

3-এ একটি কার্যকারণ হিসাবে আমি করেছি:

switch translation.x  {
case  0..<200:
    print(translation.x, slideLimit)
case  -200..<0:
    print(translation.x, slideLimit)
default:
    break
}

কাজ কিন্তু আদর্শ নয়

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