条件绑定中的绑定值必须是可选类型

时间:2021-08-12 11:15:26

I have a protocol defined:

我有一个协议定义:

protocol Usable {
    func use()
}

and a class that conforms to that protocol

以及符合该协议的类

class Thing: Usable {
    func use () {
        println ("you use the thing")
    }
}

I would like to programmatically test whether or not the Thing class conforms to the Usable protocol.

我想以编程方式测试Thing类是否符合Usable协议。

let thing = Thing()

// Check whether or not a class is useable
if let usableThing = thing as Usable { // error here
    usableThing.use()
}
else {
    println("can't use that")
}

But I get the error

但是我得到了错误

Bound value in a conditional binding must be of Optional Type

If I try

如果我试试

let thing:Thing? = Thing()

I get the error

我收到了错误

Cannot downcast from 'Thing?' to non-@objc protocol type 'Usable'

I then add @objc to the protocol and get the error

然后我将@objc添加到协议并获取错误

Forced downcast in conditional binding produces non-optional type 'Usable'

At which point I add ? after the as, which finally fixes the error.

那时我加了?在as之后,最终修复了错误。

How can I achieve this functionality with conditional binding with a non-@objc protocol, the same as in the "Advanced Swift" 2014 WWDC Video?

如何通过非@objc协议的条件绑定实现此功能,与“高级Swift”2014 WWDC视频中的相同?

5 个解决方案

#1


33  

You can get it to compile by making the cast as Usable? instead of as Usable, like this:

您可以通过将演员阵容设为可用来进行编译吗?而不是像我们这样可用:

// Check whether or not a class is useable
if let usableThing = thing as Usable? { // error here
    usableThing.use()
}
else {
    println("can't use that")
}

#2


1  

As metioned in the Swift doc, the is operator is the guy you need for the job:

正如在Swift文档中提到的那样,is运算符是你需要的工作:

The is operator checks at runtime to see whether the expression is of the specified type. If so, it returns true; otherwise, it returns false.

is运算符在运行时检查表达式是否为指定类型。如果是,则返回true;否则,它返回false。

The check must not be known to be true or false at compile time.

在编译时,检查不得为真或假。

Therefore, the following test would normally be what you need:

因此,以下测试通常是您所需要的:

if thing is Usable { 
    usableThing.use()
} else {
    println("can't use that")
}

However, as the doc specifies, Swift can detect at compile time that the expression is always true and declares an error to help the developer.

但是,正如doc指定的那样,Swift可以在编译时检测到表达式始终为true并声明错误以帮助开发人员。

#3


1  

This works for me in the playground

这适合我在操场上

protocol Usable {
    func use()
}

class Thing: Usable {
    func use () {
        println ("you use the thing")
    }
}

let thing = Thing()
let testThing : AnyObject = thing as AnyObject

if let otherThing = testThing as? Thing {
    otherThing.use()
} else {
    println("can't use that")
}

#4


0  

You are getting

你来了

Bound value in a conditional binding must be of Optional Type

because thing as Usable must return an optional type so making it as? should solved the problem. Unfortunately, the error still persisted for some odd reason. Anyway, a workaround I found to get it to work is to extract out the variable assignment inside the if statement

因为可用的东西必须返回一个可选类型,所以它作为?应该解决问题。不幸的是,由于一些奇怪的原因,错误仍然存​​在。无论如何,我发现让它工作的一种解决方法是在if语句中提取变量赋值

let thing = Thing()

let usableThing = thing as? Usable

if useableThing { 
    usableThing!.use()
}
else {
    println("can't use that")
}

#5


0  

swift protocols does not work in Playgrounds in the first beta, try to build a real project instead.

swift协议在第一个测试版的Playgrounds中不起作用,试着建立一个真正的项目。

#1


33  

You can get it to compile by making the cast as Usable? instead of as Usable, like this:

您可以通过将演员阵容设为可用来进行编译吗?而不是像我们这样可用:

// Check whether or not a class is useable
if let usableThing = thing as Usable? { // error here
    usableThing.use()
}
else {
    println("can't use that")
}

#2


1  

As metioned in the Swift doc, the is operator is the guy you need for the job:

正如在Swift文档中提到的那样,is运算符是你需要的工作:

The is operator checks at runtime to see whether the expression is of the specified type. If so, it returns true; otherwise, it returns false.

is运算符在运行时检查表达式是否为指定类型。如果是,则返回true;否则,它返回false。

The check must not be known to be true or false at compile time.

在编译时,检查不得为真或假。

Therefore, the following test would normally be what you need:

因此,以下测试通常是您所需要的:

if thing is Usable { 
    usableThing.use()
} else {
    println("can't use that")
}

However, as the doc specifies, Swift can detect at compile time that the expression is always true and declares an error to help the developer.

但是,正如doc指定的那样,Swift可以在编译时检测到表达式始终为true并声明错误以帮助开发人员。

#3


1  

This works for me in the playground

这适合我在操场上

protocol Usable {
    func use()
}

class Thing: Usable {
    func use () {
        println ("you use the thing")
    }
}

let thing = Thing()
let testThing : AnyObject = thing as AnyObject

if let otherThing = testThing as? Thing {
    otherThing.use()
} else {
    println("can't use that")
}

#4


0  

You are getting

你来了

Bound value in a conditional binding must be of Optional Type

because thing as Usable must return an optional type so making it as? should solved the problem. Unfortunately, the error still persisted for some odd reason. Anyway, a workaround I found to get it to work is to extract out the variable assignment inside the if statement

因为可用的东西必须返回一个可选类型,所以它作为?应该解决问题。不幸的是,由于一些奇怪的原因,错误仍然存​​在。无论如何,我发现让它工作的一种解决方法是在if语句中提取变量赋值

let thing = Thing()

let usableThing = thing as? Usable

if useableThing { 
    usableThing!.use()
}
else {
    println("can't use that")
}

#5


0  

swift protocols does not work in Playgrounds in the first beta, try to build a real project instead.

swift协议在第一个测试版的Playgrounds中不起作用,试着建立一个真正的项目。

相关文章