¿Cómo puedo cambiar la representación textual que se muestra para un tipo en Swift?


91

¿Cómo puedo modificar la salida textual que se muestra en la interpolación de cadenas?

El Printableprotocolo parece el más obvio, pero se ignora tanto en la Interpolación de cadenas como al imprimir la instancia, por ejemplo:

struct Point : Printable
{
    var x = 0
    var y = 0

    var description : String {
        return "(\(x), \(y))"
    }

    func toString() -> String {
        return description
    }
}

Asimismo, la toString()convención tampoco tiene efecto:

var p = Point(x: 10, y: 20)

println(p)                   // V11lldb_expr_05Point (has 2 children)
println("\(p)")              // V11lldb_expr_05Point (has 2 children)
println(p.description)       // (10, 20)
println("\(p.description)")  // (10, 20)

El comportamiento es diferente nuevamente en PlayGround, que usa su propia representación de cadena para estructuras, es decir:

p // {x 10, y 20}

¿Hay alguna forma de cambiar la forma en que se muestra una instancia?


El código anterior funciona como se esperaría en Playgrounds en Xcode 6.3 beta 4
carbo18

Respuestas:


112

Rápido 2-4

Resumen

Cumplir con el CustomStringConvertibleprotocolo y agregar description:

var description: String {
    return "description here"
}

Ejemplo

Puedes crear algunas estructuras:

struct Animal : CustomStringConvertible {
    let type : String

    var description: String {
        return type
    }
}

struct Farm : CustomStringConvertible {
    let name : String
    let animals : [Animal]

    var description: String {
        return "\(name) is a \(self.dynamicType) with \(animals.count) animal(s)."
    }
}

Si los inicializa:

let oldMajor = Animal(type: "Pig")
let boxer = Animal(type: "Horse")
let muriel = Animal(type: "Goat")

let orwellsFarm = Farm(name: "Animal Farm", animals: [oldMajor, boxer, muriel])

Las descripciones personalizadas aparecerán en su área de juegos:

ingrese la descripción de la imagen aquí

Consulte también CustomDebugStringConvertible, que puede utilizar para obtener resultados más detallados durante la depuración.


Nota de uso

Puede inicializar un Stringdesde cualquier tipo sin implementar este protocolo. Por ejemplo:

ingrese la descripción de la imagen aquí

Por esta razón, los docs dicen:

Por lo tanto, se desaconseja el uso CustomStringConvertiblecomo restricción genérica o el acceso descriptiondirecto a un tipo conforme .


37

Documentos relevantes de Apple Swift

Apple proporciona este ejemplo:

struct MyType: Printable {
    var name = "Untitled"
    var description: String {
        return "MyType: \(name)"
    }
}

let value = MyType()
println("Created a \(value)")
// prints "Created a MyType: Untitled"

Si prueba esto en el patio de recreo, obtendrá el mismo problema que está obteniendo ( V11lldb_expr...). En el patio de recreo, obtienes la descripción en el lado derecho cuando llamas al inicializador, pero printlnno devuelve algo legible.

Sin embargo, fuera del patio de recreo, este código se comporta como era de esperar. Tanto su código como el código de muestra de Apple anterior imprimen lo correcto descriptioncuando se usan en un contexto que no es un patio de juegos.

No creo que puedas cambiar este comportamiento en el patio de recreo. También podría ser un error.

EDITAR : Estoy bastante seguro de que esto es un error; Envié un informe de error a Apple.

ACTUALIZACIÓN : En Swift 2, en lugar de Printable, use CustomStringConvertible( enlace de documento relevante ).

struct MyType: CustomStringConvertible {
    var name = "Untitled"
    var description: String {
        return "MyType: \(name)"
    }
}

let value = MyType()
println("Created a \(value)")
// prints "Created a MyType: Untitled"

2

Esto parece ser un error en el patio de recreo. Si realmente compila y ejecuta el programa normalmente, imprime:

(10, 20)
(10, 20)
(10, 20)
(10, 20)

como se esperaba.

Debe informar esto en https://bugreport.apple.com


0

Si abre la vista de la consola: Ver -> Editor asistente -> Mostrar editor asistente, puede ver las líneas de impresión esperadas Verificado en xCode 6.3.2 con Yosimite 10.10

ingrese la descripción de la imagen aquí


0

Como alternativa en Swift 5+, puede extender String.StringInterpolation

struct Point {
    var x : Int
    var y : Int
}

extension String.StringInterpolation {
    mutating func appendInterpolation(_ value: Point) {
        appendInterpolation("\(value.x):\(value.y)")
    }
}

Esto cambiará el valor de print("\(p)") pero no de print(p), que seguirá usando la descripción


0

AppCodeproporciona un Generate| debugDescriptiony `` Generar | descripción`. Es mejor que escribirlos para una estructura con muchos miembros.

ingrese la descripción de la imagen aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.