การเขียนโปรแกรม 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
การเขียนโปรแกรม D รองรับฟังก์ชันที่หลากหลายและแสดงไว้ด้านล่าง
- ฟังก์ชั่นที่แท้จริง
- ฟังก์ชัน Nothrow
- ฟังก์ชั่นอ้างอิง
- ฟังก์ชั่นอัตโนมัติ
- ฟังก์ชัน Variadic
- ฟังก์ชัน 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
ฟังก์ชัน Nothrow
ฟังก์ชัน Nothrow ไม่ทิ้งข้อยกเว้นใด ๆ ที่ได้มาจาก class Exception ฟังก์ชั่น Nothrow นั้นเป็นมิตรกับคนขว้างปา
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
ฟังก์ชัน Variadic
ฟังก์ชัน Variadiac คือฟังก์ชันที่กำหนดจำนวนพารามิเตอร์สำหรับฟังก์ชันในรันไทม์ ใน 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 สามารถใช้ได้ทั้งสำหรับพารามิเตอร์และชนิดของฟังก์ชันที่ส่งคืน มันเป็นเหมือนเทมเพลตสำหรับ mutable, const และไม่เปลี่ยนรูป แอตทริบิวต์ความผันแปรถูกอนุมานจากพารามิเตอร์ หมายความว่า 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