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

时间:2021-10-18 16:35:36

What is the difference between.. (Assuming this even is type casting)

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

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

and

let cell:MessageCell = tableView.cellForRowAtIndexPath(indexPath)

i know it seems basic, but i don't really know what i'm asking specifically enough to be able to look for the right resources to help me understand this.

我知道它看起来很基本,但我真的不知道我要求具体到什么能够寻找合适的资源来帮助我理解这一点。

3 个解决方案

#1


1  

The first expression is a forced downcast.

第一个表达是强制向下倾斜。

It's used in two cases:

它用于两种情况:

  • the return type is AnyObject and has to be casted to the proper type;
  • 返回类型是AnyObject,必须转换为正确的类型;

  • the return type is a base class (UITableViewCell) and has to be casted to a subclass (MessageCell).
  • 返回类型是基类(UITableViewCell),必须转换为子类(MessageCell)。


The second expression is not a type cast, it's a type annotation

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

It's used

  • to declare the type if the type could not be inferred from the default value.

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

    From the documentation

    从文档中

    It is rare that you need to write type annotations in practice. If you provide an initial value for a constant or variable at the point that it is defined, Swift can almost always infer the type to be used for that constant or variable

    您很少需要在实践中编写类型注释。如果在定义的位置为常量或变量提供初始值,则Swift几乎总能推断出用于该常量或变量的类型

#2


0  

In Swift,

While declaring variable dataType is optional part, if you initialise it.

声明变量dataType是可选部分,如果您初始化它。

e.g.

var intValue = 5;

In above case, it will store integer value and it's dataType will be Int.

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

If you later assign value to variable, you have to specify its dataType. e.g.

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

var doubleValue : Double;
doubleValue = 2.0;

In your case

在你的情况下

let cell:MessageCell = tableView.cellForRowAtIndexPath(indexPath)

you are specifying dataType of cell, so if tableView.cellForRowAtIndexPath(indexPath) will return MessageCell type, no need to caste it again.

你正在指定cell的dataType,所以如果tableView.cellForRowAtIndexPath(indexPath)将返回MessageCell类型,则无需再次进行caste。

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

但是让let = tableView.cellForRowAtIndexPath(indexPath)为! MessageCell

you have not specified dataType for cell, so in this case it will consider its dataType as UITableViewCell because return type of cellForRowAtIndexPath: is UITableViewCell.

您没有为单元格指定dataType,因此在这种情况下,它会将其dataType视为UITableViewCell,因为cellForRowAtIndexPath:的返回类型是UITableViewCell。

But you have clear idea that it will return custom cell of type MessageCell, so to mention its dataType as MessageCell you have to forcefully unwrap it.

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

#3


0  

try to check next example in playground. properly understanding what casting is and how it works is an essential part of knowledge and if you are coming from C or ObjectiveC world, it could be very painful in the beginning ...

尝试检查操场上的下一个例子。正确理解铸件是什么以及如何工作是知识的重要组成部分,如果你来自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

#1


1  

The first expression is a forced downcast.

第一个表达是强制向下倾斜。

It's used in two cases:

它用于两种情况:

  • the return type is AnyObject and has to be casted to the proper type;
  • 返回类型是AnyObject,必须转换为正确的类型;

  • the return type is a base class (UITableViewCell) and has to be casted to a subclass (MessageCell).
  • 返回类型是基类(UITableViewCell),必须转换为子类(MessageCell)。


The second expression is not a type cast, it's a type annotation

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

It's used

  • to declare the type if the type could not be inferred from the default value.

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

    From the documentation

    从文档中

    It is rare that you need to write type annotations in practice. If you provide an initial value for a constant or variable at the point that it is defined, Swift can almost always infer the type to be used for that constant or variable

    您很少需要在实践中编写类型注释。如果在定义的位置为常量或变量提供初始值,则Swift几乎总能推断出用于该常量或变量的类型

#2


0  

In Swift,

While declaring variable dataType is optional part, if you initialise it.

声明变量dataType是可选部分,如果您初始化它。

e.g.

var intValue = 5;

In above case, it will store integer value and it's dataType will be Int.

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

If you later assign value to variable, you have to specify its dataType. e.g.

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

var doubleValue : Double;
doubleValue = 2.0;

In your case

在你的情况下

let cell:MessageCell = tableView.cellForRowAtIndexPath(indexPath)

you are specifying dataType of cell, so if tableView.cellForRowAtIndexPath(indexPath) will return MessageCell type, no need to caste it again.

你正在指定cell的dataType,所以如果tableView.cellForRowAtIndexPath(indexPath)将返回MessageCell类型,则无需再次进行caste。

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

但是让let = tableView.cellForRowAtIndexPath(indexPath)为! MessageCell

you have not specified dataType for cell, so in this case it will consider its dataType as UITableViewCell because return type of cellForRowAtIndexPath: is UITableViewCell.

您没有为单元格指定dataType,因此在这种情况下,它会将其dataType视为UITableViewCell,因为cellForRowAtIndexPath:的返回类型是UITableViewCell。

But you have clear idea that it will return custom cell of type MessageCell, so to mention its dataType as MessageCell you have to forcefully unwrap it.

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

#3


0  

try to check next example in playground. properly understanding what casting is and how it works is an essential part of knowledge and if you are coming from C or ObjectiveC world, it could be very painful in the beginning ...

尝试检查操场上的下一个例子。正确理解铸件是什么以及如何工作是知识的重要组成部分,如果你来自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