使用SQLite.Swift ...绑定时有微妙的强制警告.去任何 [英] Subtle cast warning when using SQLite.Swift ... Binding? to Any

查看:92
本文介绍了使用SQLite.Swift ...绑定时有微妙的强制警告.去任何的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是一个,

 import SQLite

    var r:[[Any]] = []

    do {
        if let stmt = try local.db?.prepare(q) {
            r = Array(stmt)
        }
        else {
            print("woe in sql?")
        }
    }
    catch { return [] }

通话

 r = Array(stmt)

赋予从绑定"隐式强制的表达?到任何.

实际上,我不知道如何提供默认值来避免此警告,如何强制展开该值来避免此警告,甚至不知道如何使用"as Any"将其强制转换为Any来使此警告静音. :O

And indeed, I do not know how to Provide a default value to avoid this warning, Force-unwrap the value to avoid this warning, or even Explicitly cast to Any with 'as Any' to silence this warning. :O

这是一个包含相同警告的独立示例:

Here's a self-contained example that reproduces the same warning:

struct Binding {}

struct Statement : IteratorProtocol, Sequence {
    func next() -> [Binding?]? {
        return nil
    }
}

let stmt = Statement()

let r: [[Any]]

r = Array(stmt) // warning: Expression implicitly coerced from 'Binding?' to Any.


相关有趣的问题:

为什么编译器...

...似乎不知道行号,有这样的问题吗?的确如此:为什么警告仅在编译后才会出现?

... appear to not know the line number, with problems like this? And indeed: why does the warning only arise once you compile?

在编译之前,大多数警告会显示在IDE中.

Most warnings appear right there in the IDE as you're typing, before compilation.

仅在编译过程中会出现(a)该警告,而编译器不知道(b)的行号.

This warning would appear to (a) only be known during compiling and (b) the compiler doesn't know the line number.

如何?有什么区别?

推荐答案

您正在使用Array

You're using Array's sequence initialiser, which has the signature:

init<S>(_ s: S) where S : Sequence, Element == S.Iterator.Element

因为您将r键入为[[Any]],所以Element[Any].但是,您传递的序列具有

Because you typed r as [[Any]], Element is [Any]. However, the sequence you're passing in has an Iterator.Element type of [Binding?]. Therefore, you're implicitly coercing Binding? to Any, and as per SE-0140, this will invoke a warning – as you're losing the optionality of the inner elements, which is potentially undesirable.

如建议所述,使该警告消失的一种方法是添加一个显式的as Any强制转换.就您而言,这可以通过使用嵌套的 map(_:) 来实现>:

As the proposal says, one way to silence this warning is to add an explicit as Any cast. In your case, this can be achieved by using a nested map(_:):

r = stmt.map { $0.map { $0 as Any } }

这不应该比使用Array的序列初始化程序花费更多,这是因为在每种情况下都必须遍历所有内部元素,因为Swift存储方式的不同类型的值(有关更多信息,请参见此问题与解答).

This shouldn't be any more costly than using Array's sequence initialiser due to the fact that a walk over all the inner elements will have to be done in either case, due to the difference in how Swift stores abstract-typed values (see this Q&A for more info).

但是,真的您应该问自己r是否应为[[Any]]类型.我认为没有理由不应该仅将其键入为[[Binding?]].这样做可以消除警告,并为您提供更好的类型安全性.

However, really you should be asking yourself whether r should be of type [[Any]]. I see no reason why you shouldn't just type it as [[Binding?]]. Doing so will both get rid of the warning and give you better type-safety.

这篇关于使用SQLite.Swift ...绑定时有微妙的强制警告.去任何的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆