简体   繁体   English

在Swift中创建没有外部属性的struct / protocol / class

[英]Create struct/protocol/class with no external properties in Swift

I have a class that wants to return a token which it alone can create and read, but can be handed to an client class which cannot do anything with it except give it back. 我有一个想要返回一个令牌的类,该令牌可以单独创建和读取,但是可以交给一个客户端类,该客户端类只能将其归还给它。 The token contains a value. 令牌包含一个值。 How can I design this so it only has private properties/methods but looks completely opaque to public. 我该如何设计它,使其仅具有私有属性/方法,但对公众完全不透明。 I don't want to do any casting, it needs to be type safe internal to the owning class. 我不想进行任何强制转换,它需要在所属类内部为类型安全。 Swift 4.x. Swift4.x。

Here's my feeble attempt. 这是我微弱的尝试。 I don't think there is a way to make a class that is completely opaque in the sense that you hide the names of all its members, but you can make them inaccessible. 我不认为有一种方法可以使一个完全不透明的类隐藏您所有成员的名称,但是您可以使它们不可访问。

struct Token {
    //everyone can see this property exists, but only 
    //classes defined in this file can see its value
    fileprivate let value: String
    init(value: String) {
        self.value = value
    }
}

I'm assuming you'll need a class for issuing and validating the tokens. 我假设您需要一个用于发布和验证令牌的类。 It will need to be able to see inside the token. 它需要能够看到令牌内部。

class TokenManager {
    func requestToken() -> Token {
        return Token(value: "a magic token value")
    }
    func isValid(token: Token) -> Bool {
        //to inspect the token's value, this class needs to be defined  
        //in the same file as the Token
        return token.value == "a magic token value"
    }
}

The consumer of the token would request a token like this: 令牌的使用者将请求这样的令牌:

    let myToken = TokenManager().requestToken()

It would know that the token has a value property, but would be unable to access it: 它会知道令牌具有value属性,但是将无法访问它:

    //print(myToken.value) //'value' is inaccessible due to 'fileprivate' protection level

But the TokenManager could inspect the token's value: 但是TokenManager可以检查令牌的值:

    let isValid = TokenManager().isValid(token: myToken)
    print(isValid) //true

You would undoubtedly want to pass some data into the requestToken method that you would validate in the isValid method, but that is, as they say, an exercise left for the reader. 毫无疑问,您希望将一些数据传递到您将在isValid方法中验证的requestToken方法中,但是正如他们所说,这是留给读者的一项练习。

Note you can't make Token a fileprivate struct because then nobody could get a token. 请注意,您不能将Tokenfileprivate struct因为这样没人会获得令牌。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM