【问题标题】:Can you overload type-casting operators in Swift?你能在 Swift 中重载类型转换运算符吗?
【发布时间】:2018-06-07 20:07:35
【问题描述】:

我想在 Swift 中实现已知类型之间的自动类型转换。 C# 的做法是重载类型转换运算符。如果我希望我的 X 类型可以与 string 交叉分配,我会写:

public class X 
{
     public static implicit operator string(X value)
     {
          return value.ToString();
     }

     public static implicit operator X(string value)
     {
          return new X(value);
     }
}

之后我可以写出类似的东西:

string s = new X();
X myObj = s;

它们会自动转换。这在 Swift 中是否有可能?

【问题讨论】:

    标签: swift casting operator-overloading


    【解决方案1】:

    不,该语言不为自定义类型提供此类功能。 Objective-C 集合和 Swift 集合之间存在桥梁,但它是内置的,不可定制。

    // Swift array of `String` elements
    let swiftArray: [String] = ["Bob", "John"] 
    
    // Obj-C array of `NSString` elements, but element type information 
    // is not known to the compiler, so it behaves like an opaque NSArray
    let nsArray: NSArray = ["Kate", "Betty"] 
    
    // Obj-C array of an `NSString` and an `NSNumber`, element type
    // information is not known to the compiler
    let heterogeneousNSArray: NSArray = ["World", 3]
    
    // Casting with `as` is enough since we're going from Swift array to NSArray 
    let castedNSArray: NSArray = swiftArray as NSArray
    
    // Force casting with `as!` is required as element type information 
    // of Obj-C array can not be known at compile time
    let castedSwiftArray: [String] = nsArray as! [String]
    
    // Obj-C arrays can not contain primitive data types and can only 
    // contain objects, so we can cast with `as` without requiring a 
    // force-cast with `!` if we want to cast to [AnyObject]
    let heterogeneousCastedNSArray: [AnyObject] = heterogeneousNSArray as [AnyObject]
    

    类型转换的文档可用here

    我认为你可以用初始化器实现你想要做的事情。

    extension X {
        init(string: String) {
            self = X(string)
        }        
    }
    
    extension String {
        init(x: X) {
            // toString is implemented elsewhere
            self = x.toString
        }        
    }
    
    let x = X()
    let string = "Bobby"
    
    let xFromString: X = X(string: string)
    let stringFromX: String = String(x: x)
    

    与您的问题没有直接关系,但还有一系列以ExpressibleBy... 开头的协议,使您能够执行以下操作: 假设我们要从整数文字初始化字符串。我们可以通过遵守和实施ExpressibleByIntegerLiteral 来做到这一点

    // Strings can not be initialized directly from integer literals
    let s1: String = 3 // Error: Can not convert value of type 'Int' to specified type 'String'
    
    // Conform to `ExpressibleByIntegerLiteral` and implement it
    extension String: ExpressibleByIntegerLiteral {
      public init(integerLiteral value: Int) {
        // String has an initializer that takes an Int, we can use that to 
        // create a string
        self = String(value)
      }
    }
    
    // No error, s2 is the string "4"
    let s2: String = 4 
    

    ExpressibleByStringLiteral 的一个很好的用例可以在 here 找到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多