D语言函数 - D语言教程

基本函数的定义

return_type function_name( parameter list )
{
   body of the function
}

一个基本的函数定义由函数头和函数体。这里是一个函数的所有部分:

  • Return Type: 函数可以返回一个值。该return_type是函数返回值的数据类型。有些函数没有返回值执行所需的操作。在这种情况下,return_type是关键字void.

  • Function Name: 这是函数的实际名称。函数名和参数列表一起构成了函数签名。

  • Parameters: 参数是像一个占位符。当调用一个函数,传递一个值给该参数。这个值被称为实际参数或参数。参数列表是指类型,顺序和一个函数的参数的数目。参数是可选的;也就是说,一个功能可以包含任何参数。

  • Function Body: 函数体包含了定义函数语句的集合。

调用函数

我们可以调用函数使用下面的语法

function_name(parameter_values)

函数类型

D编程支持广泛的函数,它们如下面列出。

  • 纯函数

  • 抛出异常函数

  • 参考函数

  • 自动函数

  • 可变参数函数

  • inout函数

  • 属性函数

各种函数功能说明。

纯函数

纯函数是无法通过他们的论据访问全局或静态的,可变的状态保存函数。这可以基于一个事实,即一个纯函数是保证变异不被传递给它什么,并在情况下,编译器可以保证纯函数不能改变它的参数,它可以启用完整,功能纯度(启用优化即保证该函数总是返回相同的结果为相同的参数)。

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));
}

When we run the above program, we will get the following output.

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中,存在具有ATLEAST一个参数的限制。但在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("    %d", j);
      }

      else if (_arguments[i] == typeid(long))
      {
         long j = va_arg!(long)(_argptr);
         writefln("    %d", j);
      }

      else if (_arguments[i] == typeid(double))
      {
         double d = va_arg!(double)(_argptr);
         writefln("    %g", d);
      }

   }
}

void main() 
{
   printargs(1, 2, 3L, 4.5);
}

当我们运行上面的程序,我们会得到下面的输出。

int    2
long    3
double    4.5

inout函数

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