我对Swift和Objective-C都不陌生,但是Error
今天在使用一个子类型时,我看到了一些奇怪的行为,这使我更加深入了。
使用NSString
子类时(是的,下面的示例对 不 基于的类具有类似的功能NSObject
):
import Foundation
// Class version
class OddString : NSString {
override var description: String {
return "No way, José"
}
}
let odd = OddString()
func printIt(_ string: NSString) {
print(string.description)
}
print(odd.description)
printIt(odd)
我看到了我期望看到的:
No way, José
No way, José
但是,当我使用struct()编写( 我认为是 )等效代码时Error
:
import Foundation
// Struct version
struct TestError : Error {
var localizedDescription: String {
return "I am a TestError"
}
}
let explosive = TestError()
func printIt(_ error : Error) {
print(error.localizedDescription)
}
print(explosive.localizedDescription)
printIt(explosive)
我懂了:
I am a TestError
The operation couldn’t be completed. (SanityChecks.TestError error 1.)
这真让我感到困惑。是否确定在 编译时 将对传入的结构调用什么方法printIt
,而不管它 实际上 是什么类型?
进一步:《 Swift编程指南》中记录了类和结构之间在运行时行为上的区别,有人可以引用此部分吗?我还没有找到任何东西。
在你的第一个例子中,你要 重写 的description
属性。因此,此实现被添加到OddString
的vtable中(因为它是一个 类
),并且可以动态地分派到正确的状态,而不管实例的静态类型是什么。
在第二个示例中,您没有类-因此没有vtables。但是,您 正在
遵守协议。协议允许通过协议见证表进行动态调度(请参阅WWDC的有关此表的详细介绍),但是这仅在协议
要求的 实现中发生。
localizedDescription
不是协议的协议要求Error
,它仅在Error
您何时使用的协议扩展中定义import Foundation
(在SE-0112中进行了说明)。因此,它不能动态调度。相反,它将是静态分派的-因此调用的实现取决于实例的 静态类型 。
这就是您在此处看到的行为–将explosive
实例键入为时TestError
,将localizedDescription
调用您的实现。当键入为时Error
,将Error
调用扩展中的实现(它只是NSError
与之连接并获取localizedDescription
)。
如果要提供本地化的描述,则应LocalizedError
改用错误类型,将其定义errorDescription
为协议要求,从而可以动态分派。
我正在使用Mapstruct映射将一个POJO转换为另一个POJO模型 以下是mapstruct自动生成的方法 该方法基本上获取源POJO的映射,并将其转换为目标模型的映射。生成正在通过。 当我运行代码时,我在这个方法中得到了ClassCast异常:HeaderAttributeGenericDataTypeMaptoStringEnergiectAttributeDataMap 堆栈跟踪: 我还
问题内容: 今天在与Swift交往时,我遇到了一件奇怪的事情。这是我开发的单元测试,显示了使用Swift的AnyObject时的一些意外行为。 这段代码简化了一些其他代码,其中只有一个Swift函数只能返回。 不出所料,在创建的实例之后,将其强制转换为并设置另一个变量,由于没有这样的属性,因此无法编译该属性。 但令人惊讶的是,编译器接受了一个名为的属性,因为on上有该名称的属性。看起来,只要它在运
问题内容: 我想用标题栏创建一个简单的框,其中包含标题和一些工具按钮。我有以下标记: 这个可以解决吗? 问题答案: 在最外面的div中指定宽度。如果内容div中的宽度表示此框的总宽度,则只需将其添加到最外面的div中,然后(可选)将其从内容中删除,如下所示:
我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方
问题内容: 当我使用双精度数在Java中将317除以219时,得到1。 例如: 输出为:1。 这是因为它是重复的小数吗?不得不使用BigDecimal代替,这很烦人。 问题答案: 试试这个 java中编码数字的默认类型是,因此使用现有的代码,java正在使用两个数字,并且除法的结果也将是,这将截断小数部分以得出最终结果。然后将此结果从转换为,而没有编译器警告,因为它是 扩大的转换 (保证源类型“适
我使用的是mongodb(v2.6.7)和mongo(2.6.7)shell客户端。 我正在尝试使用insert和update命令返回的WriteResult对象。 根据mongodocs,如果出现错误,它将返回一个writeResult对象,其中包含writeError子文档。但我无法在shell或mongo的javascript文件中访问此子文档。 下面是我的问题的说明。 我插入一个对象,并获