- D 编程基础
- D 编程 - 首页
- D 编程 - 概述
- D 编程 - 环境
- D 编程 - 基本语法
- D 编程 - 变量
- D 编程 - 数据类型
- D 编程 - 枚举
- D 编程 - 字面量
- D 编程 - 运算符
- D 编程 - 循环
- D 编程 - 条件语句
- D 编程 - 函数
- D 编程 - 字符
- D 编程 - 字符串
- D 编程 - 数组
- D 编程 - 关联数组
- D 编程 - 指针
- D 编程 - 元组
- D 编程 - 结构体
- D 编程 - 联合体
- D 编程 - 范围
- D 编程 - 别名
- D 编程 - 混合宏
- 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 是函数返回值的数据类型。有些函数执行所需的运算而不返回值。在这种情况下,返回值类型是关键字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
无异常函数
无异常函数不会抛出任何从 Exception 类派生的异常。无异常函数与抛出异常的函数是协变的。
无异常保证函数不会发出任何异常。
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
引用函数
引用函数允许函数通过引用返回值。这类似于引用函数参数。
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