在Swift中重铸时,何时使用“<object> as <type>”以及何时使用<type>(<object>)

时间:2018-02-03 20:27:40

标签: swift casting

例如,此代码有效:

while ($_row = $rsqueryapproveddata->read()) {

    if ( !isset( $list1[ $_row['DATE'] ] ) {
        $list1[ $_row['DATE'] ] = [ 'date' => $_row['DATE'] ]
    }

    $list1[ $_row['DATE'] ] [ $_row['company_id'] ] = $_row['Approved'];  

}

$result = array_values($list1);

但这不是:

var i = 5
var  str: String
str = String(i)

另一方面,这段代码有效。

str = i as String

但这不是:

let controller : MyViewController
controller = storyboard?.instantiateViewController(withIdentifier: "MyViewController") as! MyViewController

2 个答案:

答案 0 :(得分:3)

String(i)用于从另一个值创建String对象(在本例中为Int)。这是从一种类型转换为另一种类型的正确方法。这不是演员。

i as String是演员,不是转换。转换不会改变实际对象的类型。由于iInt,因此您无法将其转换为String。当您使用基类或Any获得对象的引用时,通常会执行转换,并且您希望拥有一个指定对象的实际数据类型的变量。

在第二个示例中,您声明了一个类型为myViewController的变量。据推测,这是UIViewController的子类。使用as! myViewController是有效的,因为您设置了故事板,表明标识符为"myViewController"的视图控制器的类型为myViewController。对instantiateViewController(withIdentifier:)的调用的返回类型为UIViewController。所以演员表({{​​1}})允许您指出as! myViewController确实是UIViewController。如果没有强制转换,它会失败,因为您无法将myViewController类型的值分配给UIViewController类型的变量(但您可以执行相反的操作)。

答案 1 :(得分:1)

问题的标题是:

  

什么时候使用“&lt; object&gt; as&lt; type&gt;“以及何时使用&lt; type&gt; (&lt; object&gt; )

这两种模式旨在解决非常不同的数据类型问题:

  • 当我们有某种类型的object时,我们使用前一种语法,但你碰巧知道它是(或者想要测试它是否真的)某个子类的实例那种类型,你需要/想要访问该子类特有的一些属性/方法。

    instantiateViewController示例中,该方法定义为返回UIViewControllerinstantiateViewController方法无法知道您的故事板场景是否已将某些UIViewController子类指定为该场景的“基类”,因此它返回UIViewController引用。但是您碰巧知道有问题的场景实际上会返回UIViewController的一些自定义子类,因此您可以downcast作为MyViewController子类。如果您需要与UIViewController子类特有的属性/方法进行交互,通常会这样做。

    注意,现在,您不使用as进行向下转换。如果你100%确定知道这个垮台将会成功,你可以使用as!进行强迫贬低。或者您使用as?作为一种安全方式来测试演员是否成功(例如使用if letguard let构造)。

  • 当您想要创建其他类型的全新实例时,我们使用后一种语法。

    考虑:

    let string = String(i)
    

    这实际上是在初始化期间使用String创建一个新的i实例。

    这在instantiateViewController示例中没有意义,因为我们不想从该方法返回的内容创建新的MyViewController实例。相反,我们只想告诉编译器“是的,我知道该方法将返回UIViewController(或子类)实例,但我碰巧知道它真的是MyViewController实例。”因此,在这种情况下,我们会使用as!(或as?)向下投射。

正如Martin R所指出的那样,还有其他类型的演员表(桥接演员表,AnyAnyObject类型的演员表等)。但这与你的特定例子无关。

有关强制转换的一般性讨论,请参阅 Swift编程语言的Type Casting部分。有关桥接类型,id强制转换等的讨论,请参阅Using Swift with Cocoa and Objective-C