【问题标题】:AnyObject vs. Struct (Any)AnyObject 与 Struct(任何)
【发布时间】:2015-06-06 03:58:23
【问题描述】:

我想为我的项目创建一个这样的方法:

func print(obj: AnyObject) {
    if let rect = obj as? CGRect {
        println(NSStringFromCGRect(rect))
    }
    else if let size = obj as? CGSize {
        println(NSStringFromCGSize(size))
    }

    //...
}

但我不能,因为CGRectCGSizestructs 并且不符合AnyObject protocol。那么,关于如何做到这一点的任何想法?

【问题讨论】:

    标签: ios swift struct any anyobject


    【解决方案1】:

    使用Any 而不是AnyObject

    Swift 提供了两个特殊的类型别名来处理非特定的 类型:

    AnyObject 可以表示任何类类型的实例。
    Any 可以表示任何类型的实例,包括函数类型。

    The Swift Programming Language

    【讨论】:

      【解决方案2】:

      @nkukushkin 的回答是正确的,但是,如果您想要的是一个行为不同的函数,具体取决于它是通过 CGRect 还是 CGStruct,那么您最好重载:

      func print(rect: CGRect) {
          println(NSStringFromCGRect(rect))
      }
      
      func print(size: CGSize) {
          println(NSStringFromCGSize(size))
      }
      

      相比之下,Any 效率低下(将您的结构转换为Any 并返回,如果您在紧密循环中执行此操作可能会产生很大影响),并且非类型安全(您可以通过该函数中的任何内容,它只会在运行时失败)。

      如果您的意图是将两种类型强制转换为公共类型,然后对其执行相同的操作,则可以创建采用该类型的第三个重载,并让其他两个调用它。

      【讨论】:

        【解决方案3】:

        刚刚发现了一种更好的方法。 Swift 有一个名为 dump 的方法,它可以处理多种数据。

        例如:

        dump(CGRectMake(0, 5, 30, 60))
        

        将打印:

        {x 0 y 5 w 30 h 60}
        

        【讨论】:

          【解决方案4】:

          如果您只需要打印CGRectCGSize,您可以使用:

          println(rect)
          

          println(size)
          

          您在函数末尾留下了一个“...”,因此我假设您需要打印更多类型。为此,您需要使这些类型符合Printable 协议(除非他们已经这样做了)。这是一个示例 -

          class Car { 
              var mileage = 0
          }
          
          extension Car : Printable {
              var description: String { 
                  return "A car that has travelled \(mileage) miles."
              }
          }
          

          你可以使用的:

          let myCar = Car()
          println(myCar)
          

          此外,您可能希望更改当前打印类型的方式的格式。例如,如果您希望 println(aRect)NSStringFromCGRect 返回的格式相同,则可以使用扩展名:

          extension CGRect : Printable {
              public var description: String {
                  return "{\(origin.x), \(origin.y)}, {\(size.width), \(size.height)}"
              }
          }
          

          【讨论】:

          • 是的,没错。但我认为“转储”和“NSStringFromCGRect”产生了一种更易于阅读的格式。你知道为什么吗?
          • 您是否使用 Playgrounds 来测试您的代码?我相信您的代码dump(CGRectMake(0, 5, 30, 60)) 实际上只是向您展示操场上的CGRect 的预览。试试代码let rect = CGRect(x: 0, y: 5, width: 30, height: 60); dump(rect),你应该得到和println(rect)一样的格式。
          • 我已经更新了我的答案,讨论如何在使用 println 时更改格式。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-15
          • 2020-07-09
          • 1970-01-01
          • 2016-02-09
          • 1970-01-01
          • 1970-01-01
          • 2018-05-25
          相关资源
          最近更新 更多