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
广告