- D 编程基础
- D 编程 - 主页
- D 编程 - 概述
- D 编程 - 环境
- D 编程 - 基本语法
- D 编程 - 变量
- D 编程 - 数据类型
- D 编程 - 枚举
- D 编程 - 文字
- D 编程 - 运算符
- D 编程 - 循环
- D 编程 - 决策
- D 编程 - 函数
- D 编程 - 字符
- D 编程 - 字符串
- D 编程 - 数组
- D 编程 - 关联数组
- D 编程 - 指针
- D 编程 - 元组
- D 编程 - 结构
- D 编程 - 联合
- D 编程 - 范围
- D 编程 - 别名
- D 编程 - Mixins
- D 编程 - 模块
- D 编程 - 模板
- D 编程 - 不可变
- D 编程 - 文件 I/O
- D 编程 - 并发
- D 编程 - 异常处理
- D 编程 - 合同
- D - 条件编译
- D 编程 - 面向对象
- D 编程 - 类和对象
- D 编程 - 继承
- D 编程 - 重载
- D 编程 - 封装
- D 编程 - 接口
- D 编程 - 抽象类
- D 编程 - 有用的资源
- D 编程 - 快速指南
- D 编程 - 有用的资源
- D 编程 - 讨论
D 编程 - 函数
本章介绍 D 编程中使用的函数。
D 中的函数定义
基本函数定义由函数头和函数体组成。
句法
return_type function_name( parameter list ) { body of the function }
这是函数的所有部分 -
返回类型- 函数可以返回一个值。return_type是函数返回值的数据类型。有些函数执行所需的操作而不返回值。在本例中, return_type 是关键字void。
函数名称- 这是函数的实际名称。函数名和参数列表共同构成函数签名。
参数- 参数就像占位符。当调用函数时,您将一个值传递给参数。该值称为实际参数或参数。参数列表是指函数参数的类型、顺序和数量。参数可选;也就是说,函数可以不包含参数。
函数体- 函数体包含定义函数功能的语句集合。
调用函数
您可以按如下方式调用函数 -
function_name(parameter_values)
D 中的函数类型
D 编程支持多种函数,如下所列。
- 纯函数
- 无抛出函数
- 参考功能
- 自动功能
- 可变参数函数
- 输入输出函数
- 属性功能
下面解释了各种功能。
纯函数
纯函数是无法通过其参数访问全局或静态、可变状态保存的函数。这可以基于以下事实实现优化:保证纯函数不会改变未传递给它的任何内容,并且在编译器可以保证纯函数无法更改其参数的情况下,它可以实现完整的函数纯度,即也就是说,保证函数对于相同的参数始终返回相同的结果)。
import std.stdio; int x = 10; immutable int y = 30; const int* p; pure int purefunc(int i,const char* q,immutable int* s) { //writeln("Simple print"); //cannot call impure function 'writeln' debug writeln("in foo()"); // ok, impure code allowed in debug statement // x = i; // error, modifying global state // i = x; // error, reading mutable global state // i = *p; // error, reading const global state i = y; // ok, reading immutable global state auto myvar = new int; // Can use the new expression: return i; } void main() { writeln("Value returned from pure function : ",purefunc(x,null,null)); }
当上面的代码被编译并执行时,它会产生以下结果 -
Value returned from pure function : 30
无抛出函数
Nothrow 函数不会抛出任何从 Exception 类派生的异常。Nothrow 函数与 throw 函数是协变的。
Nothrow 保证函数不会发出任何异常。
import std.stdio; int add(int a, int b) nothrow { //writeln("adding"); This will fail because writeln may throw int result; try { writeln("adding"); // compiles result = a + b; } catch (Exception error) { // catches all exceptions } return result; } void main() { writeln("Added value is ", add(10,20)); }
当上面的代码被编译并执行时,它会产生以下结果 -
adding Added value is 30
参考功能
Ref 函数允许函数通过引用返回。这类似于 ref 函数参数。
import std.stdio; ref int greater(ref int first, ref int second) { return (first > second) ? first : second; } void main() { int a = 1; int b = 2; greater(a, b) += 10; writefln("a: %s, b: %s", a, b); }
当上面的代码被编译并执行时,它会产生以下结果 -
a: 1, b: 12
自动功能
自动函数可以返回任何类型的值。对于返回的类型没有限制。下面给出了自动类型函数的一个简单示例。
import std.stdio; auto add(int first, double second) { double result = first + second; return result; } void main() { int a = 1; double b = 2.5; writeln("add(a,b) = ", add(a, b)); }
当上面的代码被编译并执行时,它会产生以下结果 -
add(a,b) = 3.5
可变参数函数
可变参数函数是那些在运行时确定函数参数数量的函数。在 C 中,存在至少一个参数的限制。但在D编程中,没有这样的限制。下面显示了一个简单的示例。
import std.stdio; import core.vararg; void printargs(int x, ...) { for (int i = 0; i < _arguments.length; i++) { write(_arguments[i]); if (_arguments[i] == typeid(int)) { int j = va_arg!(int)(_argptr); writefln("\t%d", j); } else if (_arguments[i] == typeid(long)) { long j = va_arg!(long)(_argptr); writefln("\t%d", j); } else if (_arguments[i] == typeid(double)) { double d = va_arg!(double)(_argptr); writefln("\t%g", d); } } } void main() { printargs(1, 2, 3L, 4.5); }
当上面的代码被编译并执行时,它会产生以下结果 -
int 2 long 3 double 4.5
输入输出函数
inout 既可用于函数的参数类型,也可用于返回类型。它就像可变、常量和不可变的模板。可变性属性是从参数推导出来的。意味着,inout 将推导的可变性属性传输到返回类型。下面显示了一个简单的示例,展示了可变性如何改变。
import std.stdio; inout(char)[] qoutedWord(inout(char)[] phrase) { return '"' ~ phrase ~ '"'; } void main() { char[] a = "test a".dup; a = qoutedWord(a); writeln(typeof(qoutedWord(a)).stringof," ", a); const(char)[] b = "test b"; b = qoutedWord(b); writeln(typeof(qoutedWord(b)).stringof," ", b); immutable(char)[] c = "test c"; c = qoutedWord(c); writeln(typeof(qoutedWord(c)).stringof," ", c); }
当上面的代码被编译并执行时,它会产生以下结果 -
char[] "test a" const(char)[] "test b" string "test c"
属性功能
属性允许像成员变量一样使用成员函数。它使用@property关键字。这些属性与根据要求返回值的相关函数链接。下面显示了一个简单的属性示例。
import std.stdio; struct Rectangle { double width; double height; double area() const @property { return width*height; } void area(double newArea) @property { auto multiplier = newArea / area; width *= multiplier; writeln("Value set!"); } } void main() { auto rectangle = Rectangle(20,10); writeln("The area is ", rectangle.area); rectangle.area(300); writeln("Modified width is ", rectangle.width); }
当上面的代码被编译并执行时,它会产生以下结果 -
The area is 200 Value set! Modified width is 30