Swift 协议:隐藏一些属性
Swift Protocols: hiding some properties
我想为 UITextView
和 UITextField
创建一个 trimmedText
属性。这是我所做的:
protocol TrimmedTextSupporting: class {
var _text: String? { get }
var trimmedText: String { get }
}
extension TrimmedTextSupporting {
var trimmedText: String {
let text = self._text ?? ""
return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
}
extension UITextField: TrimmedTextSupporting {
var _text: String? {
return self.text
}
}
extension UITextView: TrimmedTextSupporting {
var _text: String? {
return self.text
}
}
我需要 _text
属性 因为 text
在 UITextField
中声明为 String?
并且在 UITextView
中声明为 String!
(为什么?!>_<)。现在我想隐藏这个 属性 以避免弄乱 API.
这是我尝试过的:
1) 标记为private
。编译器不允许这样做:'private' modifier cannot be used in protocols
2) 分离成私有协议:
private protocol TextExposing {
var _text: String? { get }
}
extension UITextField: TextExposing {
var _text: String? {
return self.text
}
}
extension UITextView: TextExposing {
var _text: String? {
return self.text
}
}
///////
protocol TrimmedTextSupporting: class {
var trimmedText: String { get }
}
extension UITextField: TrimmedTextSupporting {}
extension UITextView: TrimmedTextSupporting {}
extension TrimmedTextSupporting where Self: TextExposing {
// compiler error
var trimmedText: String {
let text = self._text ?? ""
return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
}
但是编译器再次报错:
Property 'trimmedText' must be declared internal because it matches a requirement in internal protocol 'TrimmedTextSupporting'
我没主意了。
您将 TrimmedTextSupporting
声明为内部协议。如果您不想将 trimmedText
声明为 internal
,请将 TrimmedTextSupporting
声明为私有协议:
private protocol TrimmedTextSupporting: class {
var trimmedText: String { get }
}
这编译得很好。
let textView = UITextView()
textView.text = "hello "
print(textView.trimmedText) // "hello"
let textField = UITextField()
textField.text = " world "
print(textField.trimmedText) // "world"
我倾向于选择:
protocol TrimmedTextSupporting: class {
var trimmedText: String { get }
}
extension TrimmedTextSupporting {
private func trimText(text: String) -> String {
return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
}
extension UITextField: TrimmedTextSupporting {
var trimmedText: String {
return trimText(text ?? "")
}
}
extension UITextView: TrimmedTextSupporting {
var trimmedText: String {
return trimText(text ?? "")
}
}
因此,您通过在共享和私有函数中完成这些工作避免了重复工作,并且 UITextField
和 UITextView
上的扩展做了他们需要做的最少工作。
或者你可以让 trimmedText 不是必需的,设置为可选。
(如果你想在Swift中使用optional,你应该让protocol为@objc)
@objc protocol TrimmedTextSupporting: class {
optional var trimmedText: String { get }
}
我想为 UITextView
和 UITextField
创建一个 trimmedText
属性。这是我所做的:
protocol TrimmedTextSupporting: class {
var _text: String? { get }
var trimmedText: String { get }
}
extension TrimmedTextSupporting {
var trimmedText: String {
let text = self._text ?? ""
return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
}
extension UITextField: TrimmedTextSupporting {
var _text: String? {
return self.text
}
}
extension UITextView: TrimmedTextSupporting {
var _text: String? {
return self.text
}
}
我需要 _text
属性 因为 text
在 UITextField
中声明为 String?
并且在 UITextView
中声明为 String!
(为什么?!>_<)。现在我想隐藏这个 属性 以避免弄乱 API.
这是我尝试过的:
1) 标记为private
。编译器不允许这样做:'private' modifier cannot be used in protocols
2) 分离成私有协议:
private protocol TextExposing {
var _text: String? { get }
}
extension UITextField: TextExposing {
var _text: String? {
return self.text
}
}
extension UITextView: TextExposing {
var _text: String? {
return self.text
}
}
///////
protocol TrimmedTextSupporting: class {
var trimmedText: String { get }
}
extension UITextField: TrimmedTextSupporting {}
extension UITextView: TrimmedTextSupporting {}
extension TrimmedTextSupporting where Self: TextExposing {
// compiler error
var trimmedText: String {
let text = self._text ?? ""
return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
}
但是编译器再次报错:
Property 'trimmedText' must be declared internal because it matches a requirement in internal protocol 'TrimmedTextSupporting'
我没主意了。
您将 TrimmedTextSupporting
声明为内部协议。如果您不想将 trimmedText
声明为 internal
,请将 TrimmedTextSupporting
声明为私有协议:
private protocol TrimmedTextSupporting: class {
var trimmedText: String { get }
}
这编译得很好。
let textView = UITextView()
textView.text = "hello "
print(textView.trimmedText) // "hello"
let textField = UITextField()
textField.text = " world "
print(textField.trimmedText) // "world"
我倾向于选择:
protocol TrimmedTextSupporting: class {
var trimmedText: String { get }
}
extension TrimmedTextSupporting {
private func trimText(text: String) -> String {
return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
}
extension UITextField: TrimmedTextSupporting {
var trimmedText: String {
return trimText(text ?? "")
}
}
extension UITextView: TrimmedTextSupporting {
var trimmedText: String {
return trimText(text ?? "")
}
}
因此,您通过在共享和私有函数中完成这些工作避免了重复工作,并且 UITextField
和 UITextView
上的扩展做了他们需要做的最少工作。
或者你可以让 trimmedText 不是必需的,设置为可选。
(如果你想在Swift中使用optional,你应该让protocol为@objc)
@objc protocol TrimmedTextSupporting: class {
optional var trimmedText: String { get }
}