Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/118.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 修改抽象结构中的值_Ios_Swift_Swift Protocols - Fatal编程技术网

Ios 修改抽象结构中的值

Ios 修改抽象结构中的值,ios,swift,swift-protocols,Ios,Swift,Swift Protocols,我在使用结构和协议时遇到这种情况,我很想知道在这种情况下如何访问和修改值: import Foundation struct Garage { var vehicles : [VehicleProtocol] } protocol VehicleProtocol { var id: String { get } } protocol TwoWheelsProtocol: VehicleProtocol { var id: String { get } var

我在使用结构和协议时遇到这种情况,我很想知道在这种情况下如何访问和修改值:

import Foundation

struct Garage {
    var vehicles : [VehicleProtocol]
}

protocol VehicleProtocol {
    var id: String { get }
}

protocol TwoWheelsProtocol: VehicleProtocol {
    var id: String { get }
    var uniqueTwoWheelsAttribut: String { get set     }
}

struct TwoWheels: TwoWheelsProtocol {
    var id: String
    var uniqueTwoWheelsAttribut: String
}

protocol FourWheelsProtocol: VehicleProtocol {
    var uniqueFourWheelsAttribut: String { get set }
}

struct FourWheels: FourWheelsProtocol {
    var id: String
    var uniqueFourWheelsAttribut: String
}

func printVehicules(of garage: Garage) {
    for vehicle in garage.vehicles {
        if vehicle is TwoWheelsProtocol {
            let tw = vehicle as! TwoWheelsProtocol
            print("\(tw.id) | \(tw.uniqueTwoWheelsAttribut)")
        }

        if vehicle is FourWheelsProtocol {
            let tw = vehicle as! FourWheelsProtocol
            print("\(tw.id) | \(tw.uniqueFourWheelsAttribut)")
        }
    }
}

let vehicle0 = TwoWheels(id: "0", uniqueTwoWheelsAttribut: "vehicle0")
let vehicle1 = FourWheels(id: "1", uniqueFourWheelsAttribut: "vehicle1")

var a = Garage(vehicles: [vehicle0, vehicle1])

printVehicules(of: a)
打印车辆(of:a)
结果为:

0 | vehicle0
1 | vehicle1
如何修改车辆0
uniquetwoweelsattribute
,使其具有:

0 | modified
1 | vehicle1
我可以用

if a is TwoWheelsProtocol {
    let tw as! TwoWheelsProtocol
    ......
}
但是,由于cast结果在另一个变量中,修改不会影响原点值。

类具有结构所没有的其他功能:
-引用计数允许对类实例进行多个引用

所以
让tw作为!TwoWheels协议总是创建一个新对象,因为TwoWheels是一个结构。为了避免这种情况,您可以将
twoowheels
转换为一个类:

class TwoWheels: TwoWheelsProtocol {
    var id: String
    var uniqueTwoWheelsAttribut: String

    init(id: String, uniqueTwoWheelsAttribut: String) {
        self.id = id
        self.uniqueTwoWheelsAttribut = uniqueTwoWheelsAttribut
    }
}
现在
让tw作为!TwoWheelsProtocol
不会创建新副本,而只创建对对象的新引用

你能改进什么 要求
车辆协议
仅允许类实现协议。通过这种方式,您可以确保强制转换和所做的更改确实更改了引用对象,而不仅仅是其副本

protocol VehicleProtocol: class {
    var id: String { get }
}
您可以使用更紧凑的铸造方法

if var tw = vehicle as? TwoWheelsProtocol {
    // Modify tw.
}

guard var tw = vehicle as? TwoWheelsProtocol else {
    return
}
// Modify tw.

感谢伟大的解释和改进技巧。不应该是if-var而不是if-let?@Florian\u L我通常不会修改我的坏习惯。对