在Swift中扩展通用整数类型

时间:2015-08-11 13:55:36

标签: swift protocols swift2 protocol-extension

所以我试图用一些我经常使用的方便函数来扩展Swift的整数类型,但是我不清楚我应该扩展哪些协议。

作为一个例子,假设我想实现一个用于钳位值的函数(如果它小于最小值设置它,否则如果它大于最大值则将其设置为该值)。我的第一个想法是做这样的事情:

extension Int {
    func clamp(minimum:Int, maximum:Int) {
        if self < minimum { return minimum }
        if self > maximum { return maximum }
        return self
    }
}

有点简单的例子,但它说明了问题;如果我现在想要为UInt调用它,那么我自然不能,所以我必须添加等效于UInt,但这不适用于UInt16等等-on。

我认为我可能会在链上向上扩展一些东西,而是使用泛型,但IntegerType之类的协议似乎无法扩展。

那么,是否有更合适的地方可以放置我的扩展程序?

5 个答案:

答案 0 :(得分:7)

对于Swift 2,请参阅Andriy Gordiychuk的回答,这将是正确的。如果你需要Swift 1,那么这不能用扩展来完成,而且必须用免费功能来完成。这就是为什么stdlib中有如此多的自由函数成为Swift 2中的扩展。

对于Swift 1,您需要做的是:

func clamp<T:Comparable>(value: T, #minimum:T, #maximum:T) -> T {
    if value < minimum { return minimum }
    if value > maximum { return maximum }
    return value
}

如果你更喜欢修改价值(正如Andriy的例子那样),你可以这样做:

func clamp<T:Comparable>(inout value: T, #minimum:T, #maximum:T) {
    if value < minimum { value = minimum }
    else if value > maximum { value = maximum }
}

否则你必须在每种类型上写一个扩展名。这是Swift 1中唯一的其他答案.Swift 2要好得多。

答案 1 :(得分:4)

虽然Swift 2.0仍处于测试阶段,但我建议您添加如图所示的扩展程序。您必须为IntInt64等复制粘贴相同的代码,但目前没有其他方法可以执行您想要的操作。

一旦Swift 2.0问世,你就可以做到这一点

extension IntegerType {
    mutating func clamp(minimum:Self, maximum:Self) {
        if self < minimum { self = minimum }
        if self > maximum { self = maximum }
    }
}

如果您可以等到9月的某个时间发布应用程序,那么我建议您立即开始使用Swift 2.0。

更新

使用Swift 2.0,您还可以为Comparable协议添加扩展程序,以确保clamp()可用于其他类型,例如DoubleFloat

extension Comparable {
    mutating func clamp(minimum:Self, maximum:Self) {
        if self < minimum { self = minimum }
        if self > maximum { self = maximum }
    }
}

答案 2 :(得分:2)

举例来说,这是一个clamped的整数实现,它也适用于任何可以使用它的东西:

extension Comparable
{
    func clamped(from lowerBound: Self, to upperBound: Self) -> Self {
        return min(max(self, lowerBound), upperBound)
    }

    func clamped(to range: ClosedRange<Self>) -> Self {
        return min(max(self, range.lowerBound), range.upperBound)
    }
}

extension Strideable where Self.Stride: SignedInteger
{
    func clamped(to range: CountableClosedRange<Self>) -> Self {
        return min(max(self, range.lowerBound), range.upperBound)
    }
}

测试案例:

7.clamped(from: 3, to: 6)   // 6

7.clamped(to: 3 ... 6)      // 6
7.clamped(to: 3 ... 7)      // 7
7.clamped(to: 3 ... 8)      // 7

7.0.clamped(to: 3.0 ... 6.0)  // 6
7.0.clamped(to: 3.0 ... 7.0)  // 7
7.0.clamped(to: 3.0 ... 8.0)  // 7

答案 3 :(得分:1)

你走在正确的轨道上。事实上,你在谈论 string url = "external_API_URL"; HttpWebRequest request = HttpWebRequest.CreateHttp(url); request.Method = "POST"; /*Optional*/ request.KeepAlive = true; request.AllowAutoRedirect = false; request.Accept = "*/*"; request.ContentType = "application/x-www-form-urlencoded"; /*Optional*/ ////I have to pass Header parameters so adding in Headers request.Headers.Add("Header Key 1", "Header Value 1"); request.Headers.Add("Header Key 2", "Header Value 2"); request.Headers.Add("Header Key 3", "Header Value 3"); request.Headers.Add("Header Key 4", "Header Value 4"); request.Headers.Add("Header Key 5", "Header Value 5"); request.Headers.Add("Header Key 6", "Header Value 6"); ////This is the main line of code which will fetch the response from the URL WebResponse imageWebResponse = request.GetResponseAsync().Result; //// Obtain a 'Stream' object associated with the response object. Stream imageStream = imageWebResponse.GetResponseStream(); //// As we are expecting an image response set the encoding to utf-8 Encoding encode = System.Text.Encoding.GetEncoding("utf-8"); //// Read the image response StreamReader readStream = new StreamReader(imageStream, encode); ////I am converting the result to string & then i can use for Json Object or anyway i like responseImage = readStream.ReadToEnd(); //// Close all stream readStream.Close(); imageStream.Close(); imageWebResponse.Close();

  

协议扩展: Swift非常注重面向协议   开发 - 在WWDC 2015上甚至还有关于该主题的会议.Swift   2.0增加了协议扩展,标准库本身也广泛使用它们。您曾经使用全局函数的地方,Swift 2.0   现在为常见类型添加方法,因此函数链自然而然地   你的代码更具可读性。

     

https://developer.apple.com/swift/blog/?id=29

事实上,Swift 2.0的一大特色是它允许您向协议添加方法,因此您可以将Protocol Oriented Programming添加到clamp

该视频非常清楚地解释了IntegerTypehttps://developer.apple.com/videos/wwdc/2015/?id=408

的主题

您只需要升级到Swift 2.0。

答案 4 :(得分:1)

extension Comparable {
    func clamp(var minimum: Self, var _ maximum: Self) -> Self {
        if maximum < minimum { swap(&maximum, &minimum) }
        if self < minimum { return minimum }
        if self > maximum { return maximum }
        return self
    }
}