Swift中的可变参数函数介绍_Swift

可变参数函数指的是可以接受任意多个参数的函数,我们最熟悉的可能就是 NSString 的 -stringWithFormat:方法了。在 Objective-C 中,我们使用这个方法生成字符串的写法是这样的:

复制代码 代码如下:

NSString *name = @"Tom";
NSDate *date = [NSDate date];
NSString *string = [NSString stringWithFormat:
                @"Hello %@. Date: %@", name, date];

这个方法中的参数是可以任意变化的,参数的第一项是需要格式化的字符串,后面的参数都是向第一个参数中填空。在这里我们不再详细描述 Objective-C 中可变参数函数的写法 (毕竟这是一本 Swift 的书),但是我相信绝大多数即使有着几年 Objective-C 经验的读者,也很难在不查阅资料的前提下正确写出一个接受可变参数的函数。

但是这一切在Swift中得到了前所未有的简化。现在,写一个可变参数的函数只需要在声明参数时在类型后面加上 ... 就可以了。比如下面就声明了一个接受可变参数的 Int 累加函数:

复制代码 代码如下:

func sum(input: Int...) -> Int {
    //...
}

输入的 input 在函数体内部将被作为数组 [Int] 来使用,让我们来完成上面的方法吧。当然你可以用传统的 for...in 做累加,但是这里我们选择了一种看起来更 Swift的方式:

复制代码 代码如下:

func sum(input: Int...) -> Int {
    return input.reduce(0, combine: +)
}

println(sum(1,2,3,4,5))
// 输出:15

在使用可变参数时需要注意的是可变参数只能作为方法中的最后一个参数来使用,而不能先声明一个可变参数,然后再声明其他参数。这是很容易理解的,因为编译器将不知道输入的参数应该从哪里截断。另外,在一个方法中,最多只能有一组可变参数。

一个比较恼人的限制是可变参数都必须是同一种类型的,当我们想要同时传入多个类型的参数时就需要做一些变通。比如最开始提到的-stringWithFormat:方法。可变参数列表的第一个元素是等待格式化的字符串,在 Swift 中这会对应一个 String 类型,而剩下的参数应该可以是对应格式化标准的任意类型。一种解决方法是使用 Any 作为参数类型,然后对接收到的数组的首个元素进行特殊处理。不过因为 Swift 提供了使用下划线 _ 来作为参数的外部标签,来使调用时不再需要加上参数名字。我们可以利用这个特性,在声明方法是就指定第一个参数为一个字符串,然后跟一个匿名的参数列表,这样在写起来的时候就 "好像" 是所有参数都是在同一个参数列表中进行的处理,会好看很多。比如Swift 的 NSString 格式化的声明就是这样处理的:

复制代码 代码如下:

extension NSString {
    convenience init(format: NSString, _ args: CVarArgType...)
    //...
}

调用的时候就和在 Objective-C 时几乎一样了,非常方便:

复制代码 代码如下:

let name = "Tom"
let date = NSDate()
let string = NSString(format: "Hello %@. Date: %@", name, date)

时间: 2024-09-22 05:17:01

Swift中的可变参数函数介绍_Swift的相关文章

C语言中的可变参数函数的浅析(以Arm 程序中的printf()函数实现为例) .

我们在C语言编程中会遇到一些参数个数可变的函数,一般人对它的实现不理解.例如Printf():   Printf()函数是C语言中非常常用的一个典型的变参数函数,它 的原型为: int printf( const char* format, ...); 它除了一个参数format固定外,后面的参数的个数和类型是不确定的,如下列三种调用方法: 1.    printf("%d\n", i); 2.    printf("%s\n", "Hello World

C语言中实现可变参数函数

通过stdarg.h头文件为函数提供了定义可变参数列表的能力.声明一个可变参数的函数类似: void f1(int n,...); 其中n表示参数列表个数,而用省略号来表示未知参数列表.stdarg.h中提供了一个va_list类型,用于存放参数.一个大概的使用过程类似: void f1(int n,...) {    va_list ap;    va_start(ap,n);   //初始化参数列表    double first=va_arg(ap,double);  //取第一个参数  

Swift中初始化方法的顺序介绍_Swift

与 Objective-C 不同,Swift 的初始化方法需要保证类型的所有属性都被初始化.所以初始化方法的调用顺序就很有讲究.在某个类的子类中,初始化方法里语句的顺序并不是随意的,我们需要保证在当前子类实例的成员初始化完成后才能调用父类的初始化方法: 复制代码 代码如下: class Cat {     var name: String     init() {         name = "cat"     } } class Tiger: Cat {     let power

C语言“…”占位符及可变参数函数

C语言函数的参数传递总是固定了个数,那么有没有传递任意个数参数的方法呢?在C++中,函数重载提供了多种参数传递的解决办法,但也不是任意参数个数.事实上,C语言是提供任意数量参数的解决方案的. printf(),scanf()等就是这样一类可支持任意参数个数变量的函数,以下是printf的用法示例. 1 printf("%d",x); 2 printf("%f",y); 3 printf("Hello my name is %s", name);

C语言可变参数函数详解示例_C 语言

先看代码 复制代码 代码如下: printf("hello,world!");其参数个数为1个.printf("a=%d,b=%s,c=%c",a,b,c);其参数个数为4个. 如何编写可变参数函数呢?我们首先来看看printf函数原型是如何定义的.在linux下,输入man 3 printf,可以看到prinf函数原型如下: 复制代码 代码如下: SYNOPSIS#include <stdio.h>int printf(const char *form

java-[Java]关于重载方法中的可变参数列表

问题描述 [Java]关于重载方法中的可变参数列表 <Thinking in Java>第105页有一句话不理解 如何理解你应该总是只在重载方法的一个版本上使用可变参数列表,或者压根就不是用它 解决方案 就是当重载一个方法时,选择其中的一个重载使用可变参数,其他的避免使用,否则编译的时候容易出问题.具体的参看http://www.cnblogs.com/lanxuezaipiao/p/3190673.html 解决方案二: 这个道理很简单,比如说你有foo(int x int ... args

c-关于C函数指针和可变参数函数问题

问题描述 关于C函数指针和可变参数函数问题 以下程序段在linux用户空间执行成功,在内核空间执行失败,目前没有查清失败原因,所以请高手帮忙看一下! 在用户空间和内核空间分别执行以下程序段函数定义:int test_func(int a void* b){ printk(""a = %dn"" a); printk(""b = %pn"" b); return 1;} 用指针调用函数:int a = 0;int (*func)

class-c语言定义一对一对的可变参数函数

问题描述 c语言定义一对一对的可变参数函数 fund(type_1 data_1 type_2 data_2 ...); 类似这样的函数怎样定义. 解决方案 http://www.cnblogs.com/MarvinGeng/archive/2012/07/19/2598923.html 解决方案二: 定义一个参数数组作为一个参数 解决方案三: typedef struct field_pad{ UINT1 type; UINT1 len; INT1 pad[62];}field_pad_t;

浅谈Java中的可变参数_java

可变参数 可变参数就是一个方法可以接收任意多个参数!例如:fun().fun(1).fun(1,1).fun(1,1,1).你可能认为这是方法重载,但这不是重载,你想想重载能重载多少个方法,而fun()方法是可以传递任何个数的参数,你能重载这么多个方法么? 2.1 定义可变参数方法 public voidfun(int- arr) {} 上面方法fun()的参数类型为int-,其中"-"不是省略号,而是定义参数类型的方式.参数arr就是可变参数类型.你可以把上面代码理解为:public