struct MyRect : CGRect {...}
是否可以在swift中对子结构进行子类化?
我已经在Apple官方网站上找到了一个例子: 此示例扩展CGRect结构以包含计算区域属性:
extension CGRect {
var area: CGFloat {
return width * height
}
}
let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
let area = rect.area
如何定义结构的子类?
答案 0 :(得分:22)
不可能在Swift中继承struct
,只能对类进行子类化。 extension
不是子类,只是在现有struct
上添加了其他功能,这与Objective-C中的类别相当。
请参阅此处的Apple Swift文档,了解struct
和class
之间的差异。
答案 1 :(得分:2)
从Swift 5.1开始,现在可以执行与您要求的操作类似的操作:使用KeyPath
和dynamicMemberLookup
进行合成。看看:https://medium.com/@acecilia/struct-composition-using-keypath-and-dynamicmemberlookup-kind-of-struct-subclassing-but-better-6ce561768612?source=friends_link&sk=da479578032c0b46c1c69111dfb6054e
答案 2 :(得分:0)
这有点老了,但是我碰到了它,以为我会发布一个在需要时使用的通用模式。例如,我正在处理的一个应用程序需要对AspectRatios做一些工作。好吧,在我看来,AspectRatio就是带有一些附加功能的CGSize。我希望在AspectRatio和CGSize之间稍加分离,所以我创建了TypeAlias,然后创建了TypeAlias的扩展。
类似这样的东西:
#include "boost/type_traits.hpp"
template <bool enable>
struct Foo {
template <bool e = enable>
typename boost::enable_if_c<e,void>::type DoStuff(){}
};
int main(){
// Compiles
Foo<true>().DoStuff();
// Fails
Foo<false>().DoStuff();
}
然后我可以轻松地定义如下变量:
public typealias AspectRatio = CGSize
public extension AspectRatio {
enum Orientation {
case landscape
case portrait
case square
}
static let square = AspectRatio(width: 1.0, height: 1.0)
static let standard = AspectRatio(width: 4.0, height: 3.0)
static let wideScreen = AspectRatio(width: 16.0, height: 9.0)
static let theater = AspectRatio(width: 21.0, height: 9.0)
static let imax = AspectRatio(width: 1.9, height: 1.0)
func aspectRatio(precision: Int? = nil) -> CGFloat {
let aspectRatio = width / height
guard let precision = precision else {
return aspectRatio
}
let multiplier = pow(10, Double(precision))
let value = (Double(aspectRatio) * multiplier).rounded() / multiplier
return CGFloat(value)
}
var orientation: Orientation {
switch self.aspectRatio() {
case let aspect where aspect > 1.0:
return .landscape
case let aspect where aspect < 1.0:
return .portrait
default:
return .square
}
}
func flipped() -> AspectRatio {
return AspectRatio(width: height, height: width)
}
...
}