Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downcast from Any to a protocol

Tags:

ios

swift

I have the following code. How can I resolve the error in the last line?

protocol Animal {
    func walk()
}

struct Cat: Animal {
    func walk() {}

    init() { }
}

var obj: Any = Cat()
var cat = obj as Animal // ERROR: cannot downcast from Any to unrelated type Animal
like image 867
Khanh Nguyen Avatar asked Jun 19 '14 05:06

Khanh Nguyen


People also ask

What does it mean to adopt a protocol?

Adopted Protocol means the accepted method for the interchange of Messages based on such protocol as may be agreed between the Company and Barclays. Adopted Protocol means the method(s) for the Interchange of Messages between the respective Parties and an intermediary appointed.

What is downcast in Swift?

Swift Language Type Casting Downcasting operator attempts to cast to a subtype. It can fail, therefore it returns an optional.

How do you use protocols?

Protocol is used to specify particular class type property or instance property. It just specifies the type or instance property alone rather than specifying whether it is a stored or computed property. Also, it is used to specify whether the property is 'gettable' or 'settable'.

What is protocol inheritance?

One protocol can inherit from another in a process known as protocol inheritance. Unlike with classes, you can inherit from multiple protocols at the same time before you add your own customizations on top.


2 Answers

Update: This has been fixed in Swift 1.2+ (Xcode 6.3+). The Xcode 6.3 beta release notes say:

Dynamic casts (“as!", “as?" and “is”) now work with Swift protocol types, so long as they have no associated types.


You can only check for protocol conformance (which includes is, as, and as?) with an @objc protocol. Animal is not @objc.

See the Checking for Protocol Conformance section of the Swift book.

NOTE

You can check for protocol conformance only if your protocol is marked with the @objc attribute

like image 85
newacct Avatar answered Oct 24 '22 20:10

newacct


You can workaround it by doing

 var cat = obj as Cat as Animal

but this workaround is almost useless... because you need to know the type of obj first


Edit:

As @newacct point out, it is not bug, see his answer for more information

xcrun swift
Welcome to Swift!  Type :help for assistance.
  1>
  2> @objc protocol Animal {
  3.         func walk()
  4. }

@objc class Cat: Animal {
    func walk() {}

    init() { }
}

var obj: AnyObject = Cat()

var cat = obj as Animal
  5>
  6> @objc class Cat: Animal {
  7.         func walk() {}
  8.
  9.         init() { }
 10. }
 11>
 12> var obj: AnyObject = Cat()
obj: Cat = {}
 13>
 14> var cat = obj as Animal
cat: Cat = {}
 15>

Animal protocol need @objc attribute and Cat need to be @objc class.

like image 39
Bryan Chen Avatar answered Oct 24 '22 20:10

Bryan Chen