有没有办法在Swift中重写数组到字符串的转换?

时间:2016-08-19 19:56:36

标签: arrays swift swift3

我正在玩Swift试图让它看起来更“动态打字” - 只是为了好玩,没有预期的产值。

现在我无法覆盖将内置类型转换为String的行为。

例如,我想看到Array的输出结果:

let nums = [1, 2, 3]
print(nums) // "I'm an array"

到目前为止,我试图

  • NSArray(不编译)
  • 进行扩展
  • 实施CustomStringConvertible(不编译)
  • Array进行扩展(编译,不做任何更改)

好像我走错了道路:

extension Array {
    public var description: String { return "An array" }
}

至少在Swift中是否可行?

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

这不起作用,因为Array会覆盖说明。如果数组没有覆盖它,那么它将打印"数组"。课堂方法胜利'在扩展名上。

extension Array {
    public var description: String { return "An array" }
}

您可以为数组创建一个Wrapper类。这是一种解决方法,但不会覆盖数组的描述本身。

class ArrayWrapper<T> : CustomStringConvertible{
    var array : Array<T> = Array<T>()
    var description: String { return "An array" }
}

然后你可以像这样使用它。

var array = ArrayWrapper<Int>()
array.array = [1,2,3]
print(array) //prints "An Array"
print(array.array) //still prints "[1, 2, 3]"

答案 1 :(得分:0)

Swift 不允许您为已经声明该协议的类型提供协议覆盖:

<块引用> <块引用>

假设您有一组整数,并且您想覆盖一个 Set 的 CustomStringConvertible 的默认实现

对所有这些问题最简单的答案是:您不能,而且这是一项功能而不是错误。 Set 不是你的类型,你不能像这样改变它已经定义的行为。

拦截和改变类型的行为以执行与该类型最初设计的不同的功能的能力非常强大,但也充满了缺点。在这种情况下,您选择了一个相当温和的事情来改变,但在其他情况下,这样做可能会通过改变其程序范围的行为来对假设的类型的不变量造成各种损害。

改变类型以做不同的事情的最好方法是将它包装在你自己的低成本结构中。不幸的是,这确实意味着要为转发编写大量样板——尽管随着我们获得合成一致性和动态成员查找等功能,这些天越来越少。希望有一天我们会获得一些功能,让我们可以更轻松地创建具有自定义行为的新类型。

https://forums.swift.org/t/whats-the-best-way-to-override-customstringconvertible-for-a-collection/24844

答案 2 :(得分:-1)

似乎既不能子类化也不能覆盖内置Array类型。

我们可以使用包装器(信用@Yannick)并实现ArrayLiteralConvertible协议,因此我们可以使用方括号进行初始化。

struct Array<T> {
    let array: [T]
}

extension Array: ArrayLiteralConvertible {
    init(arrayLiteral elements: T...) {
        self.array = elements
    }
}

extension Array: CustomStringConvertible {
    var description: String { return "An array" }
}

let array = [1,2,3]
print(array) // "An array\n"