所以我试图用一些我经常使用的方便函数来扩展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
之类的协议似乎无法扩展。
那么,是否有更合适的地方可以放置我的扩展程序?
答案 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仍处于测试阶段,但我建议您添加如图所示的扩展程序。您必须为Int
,Int64
等复制粘贴相同的代码,但目前没有其他方法可以执行您想要的操作。
一旦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()
可用于其他类型,例如Double
,Float
等
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 现在为常见类型添加方法,因此函数链自然而然地 你的代码更具可读性。
事实上,Swift 2.0的一大特色是它允许您向协议添加方法,因此您可以将Protocol Oriented Programming
添加到clamp
。
该视频非常清楚地解释了IntegerType
:https://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
}
}