位置:首頁 > 高級語言 > D語言教學 > 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