提问者:小点点

Swift结构相当于C可变关键字?


Cmutable关键字在swift中是否有等价物?我有一个结构实现了一个包含非可变函数的协议,但是内部实现确实会改变内部状态。有没有办法通过这个函数使类的成员变量可变,而不改变协议定义,使函数可变

例如。

public protocol P {
    // f is semantically unmutating
    func f
}

public struct S : P {
    // f is semantically unmutating, but does change some internal state
    public func f {
        v += 1
    }
    private var v: Int // How to mark this as mutable for internal purposes?
    ...
}

共2个答案

匿名用户

与c中相同

public struct S : P {
    // f is semantically unmutating, but does change some internal state
    public func f {
       increment()
    }
    private mutating func increment() {
       v += 1
    }
    private var v: Int // How to mark this as mutable for internal purposes?
    ...
}

匿名用户

我认为除了将协议的语义学更改为mutatingf()之外,没有其他方法可以做到您正在尝试做的事情

您唯一的选择是创建协议PMutatingP的新变异版本,然后让结构扩展MutatingP。这可以有mutating func f()函数,您可以在结构中实现它

不过,这与另一个答案基本相同。

这是另一个非常扭曲的解决方案。但它有点满足您的要求。您需要使用两个全局变量。Int变量Vstruct S变量aStruct。代码几乎是不言自明的。这种方法的最大问题是您不能同时拥有两个struct实例。但这可以通过使用struct数组而不是单个struct来处理。

底线是它保留了协议的不变语义,但仍然允许您更改变量。使用相同的方法可以设计一种更简单的方法。

import UIKit

protocol P {
    func f()
}

var aStruct:S!
var V = 100 {
    didSet {
        print("changed V to \(V)")
        if var s = aStruct {
            s.v = 200
        }
    }
}

struct S : P  {
    var v:Int = 100 {
        didSet {
            aStruct = self
        }
    }
    init() {
        aStruct = self
    }
    func f() {
        V = 200
    }
}

let s = S()
s.f()
print("s.v = \(s.v)...aStruct.v = \(aStruct.v)")

相关问题