gpt4 book ai didi

swift - Swift 中的扩展函数、扩展静态函数和扩展类函数有什么区别?

转载 作者:搜寻专家 更新时间:2023-11-01 06:14:13 26 4
gpt4 key购买 nike

我试图在 UIColor 上创建一个扩展函数,它可以接受 Card.Colour 类型的参数并将 UIColor 返回给调用者。

button.backgroundColor = UIColor.getColour(cardColour: cardToDeal.colour)


extension UIColor {
func getColour(cardColour: Card.Colour) -> UIColor {
switch cardColour {
case .Red:
return UIColor.red
case .Green:
return UIColor.green
case .Blue:
return UIColor.blue
}
}
}

当我尝试这样做时,UIColor.getColour 的扩展函数要求我在扩展方法中输入 UIColor 类型的参数,而不是指定类型的 Card.Colour。

但是,当我将 getColour 的扩展函数更改为:

static func getColour(cardColour: Card.Colour) -> UIColor {
class func getColour(cardColour: Card.Colour) -> UIColor {

它允许我传递 Card.Colour 类型的参数

这是为什么?为什么将函数更改为静态函数或类函数会更改需要传入的类型?

提前致谢!

(非常感谢详细的回答)

最佳答案

请记住 UIColor 是一个类。类有点像您用来创建符合该类的实例或对象的蓝图。 UIColor.redUIColor 类实例的示例。

当你在一个类中定义一个 func 时(在你的例子中,作为一个扩展),Swift 假设你想将那个 func 添加到蓝图中,这将依次在 UIColor 类的所有实例中可用,例如 UIColor.red

您还可以在所有类之外定义您的 func,只需将它放在模块的顶层,而不是在 extension 中。

但是,为了让您的函数井井有条,您可以将类似的函数放在类名中。你只需要告诉 Swift 你不是要将函数添加到将应用于所有 实例 的蓝图中,而是你想要的只是拥有一个名称前缀为类的名称。

这里有一个例子来说明用法上的差异:

class Test {
func notStatic() {
print("called from an instance")
}

static func thisIsStatic() {
print("called on class name directly")
}
}

let instance = Test() // this is an *instance* of Test

instance.notStatic() // we can call a non static func on instance

Test.thisIsStatic() // we can call a static func directly on the class only

现在,让我们暂时回到您的具体示例。请注意,在您的示例中,您从 Card.Colour 的实例开始,并尝试创建 UIColor实例。

换句话说,将 func 添加到 UIColor instances(即非 staticclass) 对你没用,因为你还没有 UIColor 的实例。

创建类的新实例的惯用方法是使用初始化程序 (init)。所以你可以像这样把你的函数变成 UIColor 的初始化器:

extension UIColor {
convenience init(cardColour: Card.Colour) {
switch cardColour {
case .Red: self.init(cgColor: UIColor.red.cgColor)
case .Blue: self.init(cgColor: UIColor.blue.cgColor)
case .Green: self.init(cgColor: UIColor.green.cgColor)
}
}
}

现在您只需调用 UIColor(cardColour: .Red) 即可获得您想要的内容。请注意,在实现中,我正在将 UIColor.red 转换为 cgColor 并作为快速破解。对于 Card.Colour 的每种情况,请随意使用您认为适合 UIColor 的初始化器。

但还有另一种方式,我认为这种方式更加优雅。由于您已经拥有 Card.Colour实例,您可以使用一个函数扩展 Card.Colour,为您提供 UIColor对应实例。在该函数中,您可以使用关键字 self 引用 Card.Colour 实例。

因为您已经通过 self 获得了 Card.Colour 实例,所以您不需要向该函数传递任何参数。这使您可以使用称为计算属性 的很酷的功能来使使用更加方便。

这就是将这样的扩展添加到 Card.Colour 的方式:

extension Card.Colour {
var uiColor: UIColor {
switch self {
case .Red: return .red
case .Blue: return .blue
case .Green: return .green
}
}
}

然后您可以从 Card.Colour 中获取 UIColor,例如 Card.Colour.Red.uiColormainColour .uiColor,其中 mainColourCard.Colour 类型。

最后,正如 Leo Dabus 在评论中指出的那样,Swift's naming conventions是案例应该以小写字母开头。您应该使用 Card.Colour.red 而不是 Card.Colour.Red 等。这些约定是在 Swift 3 左右出现的。在此之前,将案例名称大写是很常见的。

关于swift - Swift 中的扩展函数、扩展静态函数和扩展类函数有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48510649/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com