Swift 可选只读变量的协议默认实现
Swift protocol default implementation for optional readonly variables
我有以下代码,协议 MyDisplayable
有三个可选的 String
,我有一个通过扩展协议的默认实现。我的问题是,因为我确定扩展名 returns 是三个字符串,有没有一种方法可以将它们用作非可选的,如果其他实现覆盖它会有任何风险吗? (见下面代码中的问题点1和2)
非常感谢!
protocol MyDisplayable {
var displayName: String? { get }
var shortDescription: String? { get }
var longDescription: String? { get }
}
protocol MyObject : MyDisplayable, CustomStringConvertible {
}
extension MyObject {
var displayName: String? {
return "noname"
}
var shortDescription: String? {
return "something can't be described"
}
var longDescription: String? {
return "no way to describe it further"
}
var description: String {
// **1. is there a way to use the strings as if they are non-optional?**
// **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?**
return "\(displayName!): \(shortDescription!)\n\(longDescription!)"
}
}
class Something : MyObject {
}
let something = Something()
print("Something: \(something)")
在您的默认实现中有条件展开怎么样?
return "\(displayName ?? "" ): \(shortDescription ?? "" )\n\(longDescription ?? "")"
遗憾的是,无法将已声明的可选项视为非可选项。
您已在协议中将这些字符串声明为可选,因此当您实施该协议时,它们仍然是可选的。
但是,您可以使用 getter-setter 来确保您的变量始终存储一些值,即使它们被声明为可选。
我会用一些代码详细说明:
protocol MyDisplayable {
var displayName: String? { get set }
var shortDescription: String? { get set }
var longDescription: String? { get set }
}
protocol MyObject : MyDisplayable, CustomStringConvertible {
}
extension MyObject {
var displayName: String? {
get {
return "noname"
}
set {
newValue ?? ""
}
}
var shortDescription: String? {
get {
return "something can't be described"
}
set {
newValue ?? ""
}
}
var longDescription: String? {
get {
return "no way to describe it further"
}
set {
newValue ?? ""
}
}
var description: String {
// **1. is there a way to use the strings as if they are non-optional?**
// **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?**
return "\(displayName!): \(shortDescription!)\n\(longDescription!)"
}
}
class Something : MyObject {
}
let something = Something()
print("Something: \(something)")
现在,即使其他 class 将 nil 值覆盖到这些字符串,它们也会 return 空字符串“”。
它们仍然是可选的,因为它们被声明为可选的,但现在它们将始终具有非零值。
我有以下代码,协议 MyDisplayable
有三个可选的 String
,我有一个通过扩展协议的默认实现。我的问题是,因为我确定扩展名 returns 是三个字符串,有没有一种方法可以将它们用作非可选的,如果其他实现覆盖它会有任何风险吗? (见下面代码中的问题点1和2)
非常感谢!
protocol MyDisplayable {
var displayName: String? { get }
var shortDescription: String? { get }
var longDescription: String? { get }
}
protocol MyObject : MyDisplayable, CustomStringConvertible {
}
extension MyObject {
var displayName: String? {
return "noname"
}
var shortDescription: String? {
return "something can't be described"
}
var longDescription: String? {
return "no way to describe it further"
}
var description: String {
// **1. is there a way to use the strings as if they are non-optional?**
// **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?**
return "\(displayName!): \(shortDescription!)\n\(longDescription!)"
}
}
class Something : MyObject {
}
let something = Something()
print("Something: \(something)")
在您的默认实现中有条件展开怎么样?
return "\(displayName ?? "" ): \(shortDescription ?? "" )\n\(longDescription ?? "")"
遗憾的是,无法将已声明的可选项视为非可选项。 您已在协议中将这些字符串声明为可选,因此当您实施该协议时,它们仍然是可选的。
但是,您可以使用 getter-setter 来确保您的变量始终存储一些值,即使它们被声明为可选。
我会用一些代码详细说明:
protocol MyDisplayable {
var displayName: String? { get set }
var shortDescription: String? { get set }
var longDescription: String? { get set }
}
protocol MyObject : MyDisplayable, CustomStringConvertible {
}
extension MyObject {
var displayName: String? {
get {
return "noname"
}
set {
newValue ?? ""
}
}
var shortDescription: String? {
get {
return "something can't be described"
}
set {
newValue ?? ""
}
}
var longDescription: String? {
get {
return "no way to describe it further"
}
set {
newValue ?? ""
}
}
var description: String {
// **1. is there a way to use the strings as if they are non-optional?**
// **2. is it a problem if another class implements the protocol and returns `nil` for any of the strings, but here they are force unwrapped?**
return "\(displayName!): \(shortDescription!)\n\(longDescription!)"
}
}
class Something : MyObject {
}
let something = Something()
print("Something: \(something)")
现在,即使其他 class 将 nil 值覆盖到这些字符串,它们也会 return 空字符串“”。 它们仍然是可选的,因为它们被声明为可选的,但现在它们将始终具有非零值。