【发布时间】:2017-09-06 00:59:36
【问题描述】:
我目前正在开发一个必须解析 URL 的 iOS 应用程序。必须解析的 URL 始终具有相同的格式。
此类 URL 的示例:
myprotocol://label?firstname=John&lastname=Smith
我的第一个想法是编写一个“解析器”class,它使用 URL 的字符串进行初始化,并具有返回 label、@987654325 的 getter 方法@and lastname 从 URL 中解析出来。
此类的伪代码:
import Foundation
class URLParser {
var url: URL
init(url: String) {
self.url = URL(string: url)
}
func label() -> String? {
// code to determine label
}
func firstname() -> String? {
// code to determine firstname
}
func firstname() -> String? {
// code to determine lastname
}
}
但后来我阅读了有关 Swift 扩展的更多信息,并看到它们在几个 places 中被使用和推荐。
对于我的用例,我可以为URL 类创建一个扩展,如下所示:
import Foundation
extension URL {
var label: String {
// code to determine label
}
var firstname: String {
// code to determine label
}
var lastname: String {
// code to determine label
}
}
一方面,使用这样的扩展似乎是个好主意,因为它感觉非常轻巧且精确。但另一方面,它也感觉有点不对劲,因为值 label、firstname 和 lastname 与 URL 的一般概念没有任何关系。它们特定于我的用例。
我想在我的代码中清楚地传达正在发生的事情,并且使用 MyUseCaseURLParser 之类的类或 URL 的扩展类(继承)称为 MyUseCaseURL 似乎做得更好。
但这一切都是基于过去使用其他语言的编程经验。
Swifty 做这样的事情并围绕它组织代码的方式是什么?除了使用扩展和类之外,还有更好的方法吗?
【问题讨论】:
-
@Honey 这个问题不是关于 where 来实现 protocols 而是更多关于 Swift 代码组织的基础知识,例如我所描述的用例.
-
听起来你的大部分问题都可以通过 URLComponents 等内置类来处理:developer.apple.com/reference/foundation/urlcomponents
-
肯定有一些习语被认为是“Swifty”,但在我看来这只是一个设计问题。您应该在惯用的 Swift 中实现您选择的设计,但不要弯曲您的设计以符合该语言用户建议的某些方法。这是一个经典的继承用例;你有一个对象可以做你想做的,但需要一些专业化。通过继承
URL,您可以将其传递给任何需要URL的方法,而无需像使用另一种方法那样不断地包装/解开“内部”URL -
@Paulw11
URL是一个struct,但是你不能继承它。