Conversión de tipos en Swift
La conversión de tipos en Swift puede determinar el tipo de una instancia. También se puede utilizar para comprobar si el tipo de una instancia pertenece a su clase padre o a su clase hija.
En Swift, la conversión de tipos se implementa con los operadores is y as. is se utiliza para comprobar el tipo de un valor, y as para convertir el tipo.
La conversión de tipos también se puede utilizar para comprobar si una clase implementa un protocolo.
Definir una jerarquía de clases
A continuación se definen tres clases: Subjects, Chemistry y Maths. Chemistry y Maths heredan de Subjects.
El código es el siguiente:
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
El resultado de la ejecución del programa anterior es:
La física de ejemplo es: Física del estado sólido La ecuación de ejemplo: Hertz La física de ejemplo es: Dinámica de fluidos La fórmula de ejemplo es: Gigahercios
Comprobar el tipo
La conversión de tipos se utiliza para comprobar si el tipo de una instancia pertenece a un tipo de instancia específico.
Puedes utilizarla en la jerarquía de clases y subclases para comprobar el tipo de una instancia de clase específica y convertir el tipo de esa instancia de clase en otros tipos de dicha jerarquía.
La comprobación de tipos utilizaisla palabra clave.
El operadorisse utiliza para comprobar si una instancia pertenece a un subtipo específico. Si la instancia pertenece a ese subtipo, el operador de comprobación de tipos devuelve true; de lo contrario, devuelve false.
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
// 如果是一个 Chemistry 类型的实例,返回 true,相反返回 false.
if item is Chemistry {
++chemCount
} else if item is Maths {
++mathsCount
}
}
print("化学科目包含 \(chemCount) 个主题,数学包含 \(mathsCount) 个主题")
El resultado de la ejecución del programa anterior es:
实例物理学是: 固体物理 实例方程式: 赫兹 实例物理学是: 流体动力学 实例公式是: 千兆赫 化学科目包含 2 个主题,数学包含 3 个主题
Conversión descendente
La conversión descendente utiliza el operador de conversión de tipos (as? o as!).
Cuando no estés seguro de que la conversión descendente tenga éxito, utiliza la forma condicional de la conversión de tipos (as?). La forma condicional de conversión de tipos siempre devuelve un valor opcional (optional value), y si la conversión descendente no es posible, el valor opcional será nil.
Solo debes utilizar la forma forzada (as!) cuando puedas estar seguro de que la conversión descendente tendrá éxito. Si intentas convertir descendientemente a un tipo incorrecto, la forma forzada de conversión de tipos provocará un error en tiempo de ejecución.
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
// 类型转换的条件形式
if let show = item as? Chemistry {
print("化学主题是: '\(show.physics)', \(show.equations)")
// 强制形式
} else if let example = item as? Maths {
print("数学主题是: '\(example.physics)', \(example.formulae)")
}
}
El resultado de la ejecución del programa anterior es:
La física de ejemplo es: Física del estado sólido La ecuación de ejemplo: Hertz La física de ejemplo es: Dinámica de fluidos La fórmula de ejemplo es: Gigahercios El tema de química es: 'Física del estado sólido', Hertz El tema de matemáticas es: 'Dinámica de fluidos', Gigahercios El tema de química es: 'Física térmica', Decibelio El tema de matemáticas es: 'Astrofísica', Megahercios El tema de matemáticas es: 'Ecuaciones diferenciales', Serie de cosenos
Conversión de tipos de Any y AnyObject
Swift proporciona dos alias de tipo especiales para tipos no especificados:
AnyObjectPuede representar una instancia de cualquier tipo de clase.AnyPuede representar cualquier tipo, incluidos los tipos de función (function types).
Nota:
Solo debes usarlo cuando realmente necesites su comportamiento y funcionalidad.AnyyAnyObject. En tu código, siempre es mejor utilizar el tipo explícito que esperas.
Instancia de Any
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
// 类型转换的条件形式
if let show = item as? Chemistry {
print("化学主题是: '\(show.physics)', \(show.equations)")
// 强制形式
} else if let example = item as? Maths {
print("数学主题是: '\(example.physics)', \(example.formulae)")
}
}
// 可以存储Any类型的数组 exampleany
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any 实例")
exampleany.append(Chemistry(physics: "固体物理", equations: "兆赫"))
for item2 in exampleany {
switch item2 {
case let someInt as Int:
print("整型值为 \(someInt)")
case let someDouble as Double where someDouble > 0:
print("Pi 值为 \(someDouble)")
case let someString as String:
print("\(someString)")
case let phy as Chemistry:
print("主题 '\(phy.physics)', \(phy.equations)")
default:
print("None")
}
}
El resultado de la ejecución del programa anterior es:
实例物理学是: 固体物理 实例方程式: 赫兹 实例物理学是: 流体动力学 实例公式是: 千兆赫 化学主题是: '固体物理', 赫兹 数学主题是: '流体动力学', 千兆赫 化学主题是: '热物理学', 分贝 数学主题是: '天体物理学', 兆赫 数学主题是: '微分方程', 余弦级数 整型值为 12 Pi 值为 3.14159 Any 实例 主题 '固体物理', 兆赫
Instancia de AnyObject
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
// [AnyObject] 类型的数组
let saprint: [AnyObject] = [
Chemistry(physics: "固体物理", equations: "赫兹"),
Maths(physics: "流体动力学", formulae: "千兆赫"),
Chemistry(physics: "热物理学", equations: "分贝"),
Maths(physics: "天体物理学", formulae: "兆赫"),
Maths(physics: "微分方程", formulae: "余弦级数")]
let samplechem = Chemistry(physics: "固体物理", equations: "赫兹")
print("实例物理学是: \(samplechem.physics)")
print("实例方程式: \(samplechem.equations)")
let samplemaths = Maths(physics: "流体动力学", formulae: "千兆赫")
print("实例物理学是: \(samplemaths.physics)")
print("实例公式是: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in saprint {
// 类型转换的条件形式
if let show = item as? Chemistry {
print("化学主题是: '\(show.physics)', \(show.equations)")
// 强制形式
} else if let example = item as? Maths {
print("数学主题是: '\(example.physics)', \(example.formulae)")
}
}
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Any 实例")
exampleany.append(Chemistry(physics: "固体物理", equations: "兆赫"))
for item2 in exampleany {
switch item2 {
case let someInt as Int:
print("整型值为 \(someInt)")
case let someDouble as Double where someDouble > 0:
print("Pi 值为 \(someDouble)")
case let someString as String:
print("\(someString)")
case let phy as Chemistry:
print("主题 '\(phy.physics)', \(phy.equations)")
default:
print("None")
}
}
El resultado de la ejecución del programa anterior es:
实例物理学是: 固体物理 实例方程式: 赫兹 实例物理学是: 流体动力学 实例公式是: 千兆赫 化学主题是: '固体物理', 赫兹 数学主题是: '流体动力学', 千兆赫 化学主题是: '热物理学', 分贝 数学主题是: '天体物理学', 兆赫 数学主题是: '微分方程', 余弦级数 整型值为 12 Pi 值为 3.14159 Any 实例 主题 '固体物理', 兆赫
En un caso de una sentencia switch, utiliza la forma forzada del operador de conversión de tipos (as, en lugar de as?) para comprobar y convertir a un tipo específico.
Otras extensiones