根据NSHipster的这个post,我们已经使用这样的文字扩展了NSURL
类来初始化NSURL
个对象:
// the following is a full fledged NSURL object
let url: NSURL = "http://nshipster.com/"
不幸的是,这篇文章是在Swift首次公布时编写的,不再编译。
我能够使自己的自定义对象符合StringLiteralConvertible
,它看起来像这样:
final class Dog {
let name: String
init(name: String) {
self.name = name
}
}
// MARK: - StringLiteralConvertible
extension Dog: StringLiteralConvertible {
typealias UnicodeScalarLiteralType = StringLiteralType
typealias ExtendedGraphemeClusterLiteralType = StringLiteralType
convenience init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
self.init(stringLiteral: value)
}
convenience init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
self.init(stringLiteral: value)
}
convenience init(stringLiteral value: StringLiteralType) {
self.init(name: value)
}
}
这很有效。例如,以下两行代码将创建一个Dog
对象:
let dog = Dog(name: "Bob")
let dog: Dog = "Bob"
不幸的是,通过扩展NSURL
来使用此策略遇到了错误:
extension NSURL: StringLiteralConvertible {
public typealias UnicodeScalarLiteralType = StringLiteralType
public typealias ExtendedGraphemeClusterLiteralType = StringLiteralType
convenience public init?(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
self.init(stringLiteral: value)
}
convenience public init?(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
self.init(stringLiteral: value)
}
convenience public init?(stringLiteral value: StringLiteralType) {
self.init(string: value)
}
}
我一直在编译错误,一次解决它们。但是,我无法通过每个初始化程序发生以下错误:
Initializer requirement 'init(...)' can only be satisfied by a 'required' initializer in the definition of non-final class 'NSURL'
添加required
关键字会给出错误,即您可能未在扩展程序中声明所需的初始值设定项。
寻找一些方向:|
答案 0 :(得分:1)
不幸的是,StringLiteralConvertible
对NSURL
的支持似乎在当前的Swift版本(2.2)中是不可能的。我能得到的最接近的是:
extension NSURL: StringLiteralConvertible {
public convenience init(stringLiteral value: String) {
self.init(string: value)!
}
public convenience init(extendedGraphemeClusterLiteral value: String) {
self.init(string: value)!
}
public convenience init(unicodeScalarLiteral value: String) {
self.init(string: value)!
}
}
但是编译器抱怨道:
Playground execution failed: OS X Playground.playground:5:24: error: initializer requirement 'init(stringLiteral:)' can only be satisfied by a `required` initializer in the definition of non-final class 'NSURL'
public convenience init(stringLiteral value: String) {
^
OS X Playground.playground:3:24: error: initializer requirement 'init(extendedGraphemeClusterLiteral:)' can only be satisfied by a `required` initializer in the definition of non-final class 'NSURL'
public convenience init(extendedGraphemeClusterLiteral value: String) {
^
OS X Playground.playground:7:24: error: initializer requirement 'init(unicodeScalarLiteral:)' can only be satisfied by a `required` initializer in the definition of non-final class 'NSURL'
public convenience init(unicodeScalarLiteral value: String) {
required
初始化程序无法在扩展程序中实现。
我们可以从另一方面简化字符串到网址的转换!
extension String {
var url: NSURL? {
return NSURL(string: self)
}
}
var url = "http://google.coom/".url
print(url?.scheme) // Optional("http")
答案 1 :(得分:0)
另一种选择是继承NSURL
并在那里符合StringLiteralConvertible
。
class URL: NSURL, StringLiteralConvertible {
<#...#>
}