我想在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中有可能吗?
答案 0 :(得分:3)
不,该语言不为自定义类型提供此类功能。 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。