这两种类型的铸造方法在swift中有什么区别

时间:2016-01-18 07:25:11

标签: swift casting swift2

有什么区别..(假设这甚至是类型转换)

let cell = tableView.cellForRowAtIndexPath(indexPath) as! MessageCell

let cell:MessageCell = tableView.cellForRowAtIndexPath(indexPath)

我知道这似乎很基本,但我并不知道我具体要求能够寻找合适的资源来帮助我理解这一点。

3 个答案:

答案 0 :(得分:1)

第一个表达式是强制向下转换

在两种情况下使用它:

  • 返回类型为AnyObject,必须将其转换为正确的类型;
  • 返回类型是基类(UITableViewCell),必须转换为子类(MessageCell)。

第二个表达式不是类型转换,它是类型注释

已使用

  • 如果无法从默认值推断出类型,则声明类型。

    来自文档

      

    您很少需要在实践中编写类型注释。如果你   在该点提供常量或变量的初始值   它被定义,Swift几乎总能推断出要用的类型   那个常数或变量

答案 1 :(得分:0)

在斯威夫特,

虽然声明变量dataType是可选部分,但如果你初始化它。

e.g。

var intValue = 5;

在上面的例子中,它将存储整数值,它的dataType将是Int。

如果稍后为变量赋值,则必须指定其dataType。 例如

var doubleValue : Double;
doubleValue = 2.0;

在你的情况下

let cell:MessageCell = tableView.cellForRowAtIndexPath(indexPath)

您指定的数据类型为cell,因此如果tableView.cellForRowAtIndexPath(indexPath)将返回MessageCell类型,则无需再次进行关联。

但在  let cell = tableView.cellForRowAtIndexPath(indexPath) as! MessageCell

您尚未为cell指定dataType,因此在这种情况下,它会将其dataType视为UITableViewCell,因为cellForRowAtIndexPath:的返回类型为UITableViewCell

但是您清楚地知道它将返回MessageCell类型的自定义单元格,因此要将其dataType称为MessageCell,您必须强行打开它。

答案 2 :(得分:0)

尝试在操场上查看下一个示例。正确理解铸造是什么以及它是如何工作的是知识的一个重要部分,如果你来自C或ObjectiveC世界,那么一开始可能会非常痛苦......

class B {
    func fb() {
        print("function defined in B.Type")
    }
}
class C: B{
    func fc() {
        print("function defined in C.Type")
    }
}
class D {}

func foo(t: Bool)->B! {
    if t {
        return C()
    } else {
        return nil
    }
}

let c0 = foo(true)
print("casting c0 is C returns:", c0 is C, " ,BUT c0 dynamic type is", c0.dynamicType)
// casting c0 is C returns: true, BUT c0 dynamic type is ImplicitlyUnwrappedOptional<B>
c0.fb() // function defined in B.Type

// but next line doesn't compile!! (try to 'uncomment it...)
//c0.fc() // error: value of type 'B' has no member 'fc'


let c1 = foo(true) as! C
c1 is C // compiler warns you that 'is' test always true :-)
c1.fb() // function defined in B.Type
c1.fc() // function defined in C.Type

// next lines don't compile !! (try to 'uncomment it...)
//let d0: D = foo(true) // error: cannot convert value of type 'B!' to specified type 'D'
//let c2: C = foo(true)    // error: cannot convert value of type 'B!' to specified type 'C'

...

// and finaly, next line compile with warning and (yes, unfortunately) crash :-)
let d = foo(true) as! D // crash you code