কোনও বস্তু সুইফটে প্রদত্ত ধরণের কিনা তা পরীক্ষা করা হচ্ছে


267

আমার তৈরি একটি অ্যারে রয়েছে AnyObject। আমি এটির উপরে পুনরাবৃত্তি করতে চাই এবং অ্যারে দৃষ্টান্তগুলিতে থাকা সমস্ত উপাদানগুলি সন্ধান করতে চাই।

কীভাবে আমি কীভাবে চেক করতে পারি যে কোনও বস্তু সুইফটে প্রদত্ত ধরণের কিনা?


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

আমি এই প্রশ্নটি স্ট্যাকওভারফ্লো.com / q / 24093433 থেকে বিচ্ছিন্ন করতে সম্পাদনা করেছি , যা আমি আবার খুলতে ভোট দিচ্ছি। এগুলি উভয়ই কার্যকর, অনুরূপ, প্রশ্ন, তবে উত্তরগুলি একেবারে স্বতন্ত্র তাই তাদের পৃথক রাখা কার্যকর হবে।
জেরেমি ব্যাংকগুলি

উত্তর:


304

আপনি যদি কোনও নির্দিষ্ট ধরণের বিরুদ্ধে পরীক্ষা করতে চান তবে নিম্নলিখিতগুলি করতে পারেন:

if let stringArray = obj as? [String] {
    // obj is a string array. Do something with stringArray
}
else {
    // obj is not a string array
}

আপনি "হিসাবে!" ব্যবহার করতে পারেন এবং এটি objটাইপ না হলে একটি রানটাইম ত্রুটি নিক্ষেপ করবে[String]

let stringArray = obj as! [String]

আপনি একবারে একটি উপাদান পরীক্ষা করতে পারেন:

let items : [Any] = ["Hello", "World"]
for obj in items {
   if let str = obj as? String {
      // obj is a String. Do something with str
   }
   else {
      // obj is not a String
   }
}

কেন এটি কেবল একটি রানটাইম ত্রুটি নিক্ষেপ করবে এবং ?উপস্থিত নেই যখন একটি সংকলন সময় ত্রুটি । দেখে মনে হচ্ছে asএবং ?যখন মিলিত হবে রানটাইম চেক করবে। কখন ব্যবহার asছাড়া উপযুক্ত হবে ?? আগাম ধন্যবাদ.
আনহেলিগ

@Unheilig আপনি শুধুমাত্র ব্যবহার করা উচিত asছাড়া ?যদি কোন উপায় আপনার প্রোগ্রাম থেকে অবজেক্ট কারণ প্রোগ্রাম অবিলম্বে যদি না হয় তাহলে থেমে যাবে যে ধরনের হচ্ছে না পুনরুদ্ধার করতে পারে। ব্যবহার ?মধ্যে ifবিবৃতি অব্যাহত রাখার জন্য প্রোগ্রাম পারেন।
ড্র্যাগ করুন

প্রতিক্রিয়া জন্য ধন্যবাদ। আমি ভুল হলে আমাকে সংশোধন করুন: আমি ভেবেছিলাম যে ?এই ক্ষেত্রেটি ব্যবহার করে "জেনেরিক" প্রকারের চেক করা হবে, যদি হ্যাঁ, তবে যদি এই অনুচ্ছেদে, যদি না হয়, তবে অন্য ধারাটিতে। ?অন্যটি ছাড়া কখনও প্রবেশ করা যাবেনা এবং আপনি যেমনটি নির্দেশ করেছেন তেমন একটি রানটাইম ত্রুটির কারণ হবে। আবার ধন্যবাদ.
আনহেলিগ

@ আনহেলিগ আমি দুঃখিত, আপনি কী বলছেন / জিজ্ঞাসা করছেন তা আমি বুঝতে পারি না। ?নিয়োগ ফিরে যাওয়ার অনুমতি দেয় nilরিটার্ন যদি বিবৃতি ঘটাচ্ছে falseএবং সেইজন্য অন্য বিবৃতি মাধ্যমে পতনশীল। যাইহোক, আমি মনে করি ব্যাখ্যাটি বোঝার সাথে সহায়তা করে তবে if letএটি
সংকলকটিতে

1
সঠিক @Unheilig, আপনি Var ব্যবহার করতে পারেন যদি আপনি যখন যে স্থানীয় সুযোগ (যারা পরিবর্তন বাহিরে সুযোগ প্রভাবিত করবে না) মান পরিবর্তন করতে পারবেন হতে চাই
drewag

202

ইন সুইফট 2.2 - 5 তুমি এখন কি করতে পারেন:

if object is String
{
}

তারপরে আপনার অ্যারে ফিল্টার করতে:

let filteredArray = originalArray.filter({ $0 is Array })

আপনার যদি চেক করার একাধিক প্রকার থাকে:

    switch object
    {
    case is String:
        ...

    case is OtherClass:
        ...

    default:
        ...
    }

এই সমাধানটি সংক্ষিপ্ত, তবে এর একটি অসুবিধা রয়েছে: আপনি বন্ধনীগুলির অভ্যন্তরের objectহিসাবে String(কমপক্ষে সুইফট 2 এ) ব্যবহার করতে পারবেন না , তবে letসমাধানের সাথে আপনি এটি করতে পারেন।
ফেরান মেলিনঞ্চ

@FerranMaylinch- এর অর্থ আপনার বোঝা যা বুঝতে পারছেন না কারণ objectব্লকটিতে ব্যবহার করা ভাল।
অর্থ-বিষয়গুলি

@ অর্থ-বিষয়গুলি উদাহরণস্বরূপ আপনি করতে সক্ষম হবেন না object.uppercaseStringকারণ ভেরিয়েবলের ধরণটি সেই ধরণের হয়ে থাকে না, আপনি কেবল পরীক্ষা করেছেন যে বস্তুটি (ভেরিয়েবল দ্বারা নির্দেশিত) একটিString
ফেরান মেলিনিঞ্চ

আপনি যে শ্রেণীর ধরণের জন্য যাচাই করছেন তা যদি স্বেচ্ছাচারিত হয় তবে আপনি এটি কীভাবে করতে পারেন? আপনার যদি কেবল একটি ভেরিয়েবল থাকে তবে আপনার কাছ থেকে কোনও শ্রেণির ধরণের পাওয়া দরকার?
অ্যালেক্স জাভাটোন

152

আপনি শুধুমাত্র যদি একটি বস্তু জানতে চান হয় একটি প্রদত্ত ধরনের উপপ্রকার তারপর সহজ পন্থা:

class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}

func area (shape: Shape) -> Double {
  if shape is Circle { ... }
  else if shape is Rectangle { ... }
}

“উদাহরণটি একটি নির্দিষ্ট সাবক্লাসের ধরণের কিনা তা পরীক্ষা করার জন্য টাইপ চেক অপারেটর (এটি) ব্যবহার করুন। প্রকারের চেক অপারেটরটি সত্যটি প্রত্যাবর্তন করে যদি উদাহরণটি সেই সাবক্লাসের হয় এবং তা যদি মিথ্যা না হয়। " এর উত্স: অ্যাপল ইনক। "দ্য সুইফ্ট প্রোগ্রামিং ভাষা।" iBooks

উপরের বাক্যাংশে 'একটি নির্দিষ্ট সাবক্লাস টাইপের' শব্দটি গুরুত্বপূর্ণ is ব্যবহারের is Circleএবং is Rectangleকম্পাইলার দ্বারা গৃহীত কারণ যে মান হয় shapeহিসাবে ঘোষণা করা হয় Shape(একটি সুপারক্লাস Circleএবং Rectangle)।

আপনি যদি আদিম ধরণের ব্যবহার করেন তবে সুপারক্লাসটি হবে Any। এখানে একটি উদাহরণ:

 21> func test (obj:Any) -> String {
 22.     if obj is Int { return "Int" }
 23.     else if obj is String { return "String" }
 24.     else { return "Any" }
 25. } 
 ...  
 30> test (1)
$R16: String = "Int"
 31> test ("abc")
$R17: String = "String"
 32> test (nil)
$R18: String = "Any"

2
আমি যদি একটি অ্যারেতে আদিম প্রকার সংরক্ষণ করি বা অ্যারে যদি আদিম ধরণের এক, তবে isএখনও এখানে কাজ করবে ? ধন্যবাদ।
আনহেলিগ

আপনি যদি এটি objectহিসাবে ঘোষণা করেন তবে এটি কাজ করা উচিত Any। একটি উদাহরণ সহ আপডেট করা হয়েছে।
GoZoner

উত্তর দেওয়ার জন্য ধন্যবাদ. এটি আশাব্যঞ্জক মনে হচ্ছে। আমার একমাত্র সন্দেহ হ'ল নীচের উত্তর অনুসারে, যার AnyObjectমধ্যে প্রস্তাব দেওয়া হয়েছে, AnyObjectউত্তরাধিকারসূত্রে না পাওয়ায় প্রতিশোধ নেওয়া হয়েছে বলে মনে হয় NSObject। যদি Anyআলাদা হয়, তবে এটি আসলে একটি দুর্দান্ত সমাধানও হবে। ধন্যবাদ।
আনহেলিগ

21

আমার এটি করার 2 টি উপায় রয়েছে:

if let thisShape = aShape as? Square 

বা:

aShape.isKindOfClass(Square)

এখানে একটি বিস্তারিত উদাহরণ:

class Shape { }
class Square: Shape { } 
class Circle: Shape { }

var aShape = Shape()
aShape = Square()

if let thisShape = aShape as? Square {
    println("Its a square")
} else {
    println("Its not a square")
}

if aShape.isKindOfClass(Square) {
    println("Its a square")
} else {
    println("Its not a square")
}

সম্পাদনা করুন: 3 এখন:

let myShape = Shape()
if myShape is Shape {
    print("yes it is")
}

1
isKindOfClassNSObjectপ্রোটোকলের একটি পদ্ধতি ; এটি কেবল এটি গ্রহণকারী ক্লাসগুলির জন্য কাজ করা উচিত (এনএসবজেক্ট থেকে আগত সমস্ত শ্রেণি, এবং এটির সাথে স্পষ্টভাবে গ্রহণ করে এমন কোনও কাস্টম সুইফ্ট শ্রেণি)
নিকোলাস মিয়ারি


9

ধরে drawTriangle একটি উদাহরণ draw ড্রইট্রিঙ্গনটি ইউআইটিএবলভিউর টাইপের কিনা তা পরীক্ষা করতে:

ইন সুইফট 3 ,

if drawTriangle is UITableView{
    // in deed drawTriangle is UIView
    // do something here...
} else{
    // do something here...
}

এটি নিজের দ্বারা নির্ধারিত ক্লাসগুলির জন্যও ব্যবহার করা যেতে পারে। আপনি কোনও দৃশ্যের সংক্ষিপ্তসারগুলি পরীক্ষা করতে এটি ব্যবহার করতে পারেন।



5

এ সম্পর্কে সতর্ক হতে:

var string = "Hello" as NSString
var obj1:AnyObject = string
var obj2:NSObject = string

print(obj1 is NSString)
print(obj2 is NSString)
print(obj1 is String)
print(obj2 is String) 

চারটি শেষ লাইন সমস্ত সত্য ফিরে আসে, এটি কারণ যদি আপনি টাইপ করেন

var r1:CGRect = CGRect()
print(r1 is String)

... এটি অবশ্যই "মিথ্যা" মুদ্রণ করে তবে একটি সতর্কতা বলে যে সিজিআরেক্ট থেকে স্ট্রিংয়ের কাস্ট ব্যর্থ হয়। সুতরাং কিছু প্রকারের ব্রিজ করা হয়েছে, উত্তরগুলি 'হ'ল কীওয়ার্ডটি একটি অন্তর্নিহিত castালাকে কল করে।

আপনার এইগুলির একটি ভাল ব্যবহার করা উচিত:

myObject.isKind(of: MyClass.self)) 
myObject.isMember(of: MyClass.self))

2

যদি আপনি অব্যবহৃত সংজ্ঞায়িত মানটির কারণে কোনও সতর্কতা না পেয়ে ক্লাসটি পরীক্ষা করতে চান তবে (কিছুটা পরিবর্তনযোগ্য ...), আপনি কেবল বুলিয়ান দিয়ে লেট স্টাফগুলি প্রতিস্থাপন করতে পারেন:

if (yourObject as? ClassToCompareWith) != nil {
   // do what you have to do
}
else {
   // do something else
}

এক্সকোড এটি প্রস্তাব করেছিল যখন আমি লেট ওয়ে ব্যবহার করি এবং সংজ্ঞায়িত মানটি ব্যবহার করি না।


2

এই জাতীয় কিছু ব্যবহার করবেন না কেন

fileprivate enum types {
    case typeString
    case typeInt
    case typeDouble
    case typeUnknown
}

fileprivate func typeOfAny(variable: Any) -> types {
    if variable is String {return types.typeString}
    if variable is Int {return types.typeInt}
    if variable is Double {return types.typeDouble}
    return types.typeUnknown
}

সুইফ্ট 3 এ


2

সুইফট ৪.২, আমার ক্ষেত্রে, আইসকিন্ড ফাংশন ব্যবহার করে।

isKind (of :) একটি বুলিয়ান মান প্রদান করে যা নির্দেশ করে যে প্রাপক প্রদত্ত শ্রেণীর উদাহরণ বা কোনও শ্রেণীর উদাহরণ যা সেই শ্রেণীর উত্তরাধিকার সূত্রে প্রাপ্ত।

  let items : [AnyObject] = ["A", "B" , ... ]
  for obj in items {
    if(obj.isKind(of: NSString.self)){
      print("String")
    }
  }

রিডমোর https://developer.apple.com/docamentation/objectivec/nsobjectprotocol/1418511- জাতিজা


1
এটি সুইফট নয়। এটি কোকো এবং এটি কেবল যেখানে কাজ করে এটির উদ্দেশ্য সি
ম্যাট

1

myObject as? Stringnilযদি myObjectনা হয় তবে ফেরত দেয় String। অন্যথায়, এটি একটি ফেরত দেয় String?, যাতে আপনি নিজেই স্ট্রিংটি অ্যাক্সেস করতে পারেন myObject!বা myObject! as Stringনিরাপদে এটি কাস্ট করতে পারেন ।



1

কেবল গৃহীত উত্তরের উপর ভিত্তি করে সম্পূর্ণতার স্বার্থে এবং কিছু অন্যান্য:

let items : [Any] = ["Hello", "World", 1]

for obj in items where obj is String {
   // obj is a String. Do something with str
}

তবে আপনি ( compactMapমানগুলি "মানগুলিও করতে পারেন যা filterদেয় না):

items.compactMap { $0 as? String }.forEach{ /* do something with $0 */ ) }

এবং একটি সংস্করণ ব্যবহার করে switch:

for obj in items {
    switch (obj) {
        case is Int:
           // it's an integer
        case let stringObj as String:
           // you can do something with stringObj which is a String
        default:
           print("\(type(of: obj))") // get the type
    }
}

তবে প্রশ্নটির সাথে লেগে থাকা, এটি একটি অ্যারে (যেমন [String]) কিনা তা পরীক্ষা করে দেখুন :

let items : [Any] = ["Hello", "World", 1, ["Hello", "World", "of", "Arrays"]]

for obj in items {
  if let stringArray = obj as? [String] {
    print("\(stringArray)")
  }
}

বা আরও সাধারণভাবে ( এই অন্যান্য প্রশ্নের উত্তর দেখুন ):

for obj in items {
  if obj is [Any] {
    print("is [Any]")
  }

  if obj is [AnyObject] {
    print("is [AnyObject]")
  }

  if obj is NSArray {
    print("is NSArray")
  }
}

1

as?সর্বদা আপনাকে প্রত্যাশিত ফলাফল asদেয় না কারণ কোনও ডেটা টাইপ নির্দিষ্ট ধরণের হয় কিনা তা পরীক্ষা করে না তবে কেবল যদি কোনও ডেটা টাইপকে নির্দিষ্ট ধরণের রূপান্তর করা যায় বা প্রতিনিধিত্ব করা যায়

উদাহরণস্বরূপ এই কোডটি বিবেচনা করুন:

func handleError ( error: Error ) {
    if let nsError = error as? NSError {

Errorপ্রোটোকল অনুসারে প্রতিটি ডাটা টাইপ কোনও NSErrorবস্তুতে রূপান্তরিত হতে পারে , তাই এটি সর্বদা সফল হবে । তবুও এর অর্থ এই নয় যে errorএটি আসলে কোনও NSErrorবস্তু বা এটির একটি সাবক্লাস।

একটি সঠিক ধরণের চেক হবে:

func handleError ( error: Error ) {
    if type(of: error) == NSError.self {

যাইহোক, এই সঠিক ধরণের জন্য পরীক্ষা করে। আপনি যদি সাবক্লাসের অন্তর্ভুক্ত করতে চান তবে আপনার NSErrorব্যবহার করা উচিত:

func handleError ( error: Error ) {
    if error is NSError.Type {

0

আপনার যদি মতামত থাকে তবে:

{
  "registeration_method": "email",
  "is_stucked": true,
  "individual": {
    "id": 24099,
    "first_name": "ahmad",
    "last_name": "zozoz",
    "email": null,
    "mobile_number": null,
    "confirmed": false,
    "avatar": "http://abc-abc-xyz.amazonaws.com/images/placeholder-profile.png",
    "doctor_request_status": 0
  },
  "max_number_of_confirmation_trials": 4,
  "max_number_of_invalid_confirmation_trials": 12
}

এবং আপনি যে মানটিকে is_stuckedযেকোনওবজেক্ট হিসাবে পড়া হবে তা পরীক্ষা করতে চান, আপনাকে যা করতে হবে তা হ'ল

if let isStucked = response["is_stucked"] as? Bool{
  if isStucked{
      print("is Stucked")
  }
  else{
      print("Not Stucked")
 }
}

0

আপনি যদি না জানেন যে আপনি সার্ভারের প্রতিক্রিয়াতে অভিধান বা একক অভিধানের একটি অ্যারে পাবেন আপনার ফলাফলটি একটি অ্যারে রয়েছে কিনা তা যাচাই করতে হবে।
আমার ক্ষেত্রে সর্বদা একবার ছাড়া অভিধানের একটি অ্যারে গ্রহণ করা হয়। সুতরাং, হ্যান্ডেল করতে আমি সুইফট 3 এর জন্য নীচের কোডটি ব্যবহার করেছি।

if let str = strDict["item"] as? Array<Any>

এখানে যেমন? অ্যারে প্রাপ্ত মানটি অ্যারে (অভিধানের আইটেমগুলির) কিনা তা পরীক্ষা করে। অন্যথায় আপনি যদি পরিচালনা করতে পারেন তবে এটি যদি একক অভিধানের আইটেম হয় যা অ্যারের ভিতরে রাখা হয় না।


0

সুইফ্ট 5.2 এবং এক্সকোড সংস্করণ: 11.3.1 (11 সি 504)

এখানে ডেটা প্রকার পরীক্ষা করার আমার সমাধানটি দেওয়া হল:

 if let typeCheck = myResult as? [String : Any] {
        print("It's Dictionary.")
    } else { 
        print("It's not Dictionary.") 
    }

আমি আশা করি এটা তোমাকে সাহায্য করবে।


কোনও পুরানো প্রশ্নের উত্তর দেওয়ার সময়, আপনার উত্তরটি অন্যান্য স্ট্যাকওভারফ্লো ব্যবহারকারীদের কাছে অনেক বেশি কার্যকর হবে যদি আপনি আপনার উত্তরটি কীভাবে সহায়তা করে তা ব্যাখ্যা করার জন্য কিছু প্রসঙ্গ অন্তর্ভুক্ত করে, বিশেষত ইতিমধ্যে স্বীকৃত উত্তর রয়েছে এমন একটি প্রশ্নের জন্য। দেখুন: আমি কীভাবে ভাল উত্তর লিখব
ডেভিড বক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.