Swift:String.join()如何处理自定义类型?
例如:Swift:String.join()如何处理自定义类型?,swift,Swift,例如: var a = [1, 2, 3] // Ints var s = ",".join(a) // EXC_BAD_ACCESS 是否可以使连接函数返回“1,2,3” 扩展Int(或其他自定义类型)以符合某些协议?试试这个 var a = [1, 2, 3] // Ints var s = ",".join(a.map { $0.description }) 或添加此扩展名 extension String { func join<S : SequenceT
var a = [1, 2, 3] // Ints
var s = ",".join(a) // EXC_BAD_ACCESS
是否可以使连接函数返回“1,2,3”
扩展Int(或其他自定义类型)以符合某些协议?试试这个
var a = [1, 2, 3] // Ints
var s = ",".join(a.map { $0.description })
或添加此扩展名
extension String {
func join<S : SequenceType where S.Generator.Element : Printable>(elements: S) -> String {
return self.join(map(elements){ $0.description })
}
// use this if you don't want it constrain to Printable
//func join<S : SequenceType>(elements: S) -> String {
// return self.join(map(elements){ "\($0)" })
//}
}
var a = [1, 2, 3] // Ints
var s = ",".join(a) // works with new overload of join
扩展字符串{
func连接(元素:S)->字符串{
返回self.join(映射(元素){$0.description})
}
//如果不希望将其约束为可打印,请使用此选项
//func连接(元素:S)->字符串{
//返回self.join(映射(元素){“\($0)”})
//}
}
变量a=[1,2,3]//整数
var s=“,”.join(a)//用于join的新重载
联接定义为
extension String {
func join<S : SequenceType where String == String>(elements: S) -> String
}
扩展字符串{
func连接(元素:S)->字符串
}
这意味着它需要一个字符串序列,您不能将int序列传递给它。即使您不能使join对自定义类型起作用,也有一个简单的解决方法。 您所要做的就是在类(或扩展内置类)上定义一个方法以返回字符串,然后将其映射到联接中 例如,我们可以:
extension Int {
func toString() -> String {
return "\(self)" // trivial example here, but yours could be more complex
}
然后你可以做:
let xs = [1, 2, 3]
let s = join(xs.map { $0.toString() })
我不建议为此使用.description
,因为默认情况下它将调用.debugDescription
,这在生产代码中并不特别有用
在任何情况下,最好提供一个显式方法来转换为适合连接的字符串,而不是依赖于一个通用的“描述”方法,您可能会在以后更改该方法。最简单的方法是@BryanChen答案的变体:
",".join(a.map { String($0) } )
从Swift 2中的Xcode 7.0 beta 6开始,现在您应该使用
[String].joinWithSeparator(“,”)
在您的例子中,仍然需要将Int更改为String类型,因此我添加了
map()
从Swift 3中的Xcode 8.0 beta 1代码略微更改为
[String]。已加入(分隔符:“,”)
为了使您的生活更加完整,从Swift 3中的Xcode 8.0 beta 1开始,您现在应该使用
[String].joined(分隔符:“,”
)
这是Swift API的新“ed/ing”命名规则:
根据其副作用命名功能和方法
- 那些没有副作用的应该读作名词短语,例如x.distance(to:y),i.继任者()
- 有副作用的应该读作祈使动词短语,例如print(x),x.sort(),x.append(y)
- 名称突变/非突变方法对一致。突变方法通常会有一个语义相似的非突变变量,但它会返回一个新值,而不是就地更新实例。
public extension Sequence where Iterator.Element: CustomStringConvertible {
func joined(seperator: String) -> String {
return self.map({ (val) -> String in
"\(val)"
}).joined(separator: seperator)
}
}
debugDescription
用于调试,而不是description
@BryanChen这是真的,但值得注意的是后者的NSObject
实现调用了前者。我将编辑我的帖子以澄清。这比使用结果不能保证的description
要好String()
保证生成String
@Zaph“结果不保证”是什么意思?description
字段用于提供人类可读的描述。对于Int
,通常是将数字转换为字符串表示形式。但是作为一个(计算的)属性,它可以被重写,尽管对于Int
@Antonio,这种情况不太可能发生,我仍然不明白。字符串(1)
是否保证其值?如果您重写(您不能为Int
)description
,您可能是指它(尽管这是一个坏主意)字符串(1)保证生成包含“1”的字符串。现在Int.description
返回“1”,但可能明天苹果决定将其实现更改为返回“(Int)1”或其他内容<代码>说明用于提供对象的字符串说明,而不是将对象转换为字符串。这就是说,如果您仍然使用说明
,那么它现在就可以工作了。明天可能不会如你所期望的那样。我不喜欢第二个未发表评论的建议。它似乎不够健壮或通用。依靠这样的描述似乎是错误的。另外,注释选项(使用($0))在IMO中并不令人惊讶。它在使用“join”操作时打开了到字符串的隐式转换。用户甚至不知道它发生了。在我看来,简单地使用就地映射更为冗长,也更具可读性。
var s3 = a.map { String($0) }.joined(separator: ",") // "1,2,3"
public extension Sequence where Iterator.Element: CustomStringConvertible {
func joined(seperator: String) -> String {
return self.map({ (val) -> String in
"\(val)"
}).joined(separator: seperator)
}
}