- D Cookbook
- Adam D. Ruppe
- 889字
- 2021-07-16 11:50:44
Creating a user-defined vector type
User-defined types are used everywhere in D to group data, model objects, provide compile-time checks, and more. Here, you'll create a simple vector type with a length and direction to look at some basic capabilities.
Getting ready
Whenever you create a user-defined collection in D, the first decision to make is whether it should be a class, struct, mixin template, or union. Mixin templates are great for code reuse. They define code that can be copied (or mixed in) to another type, with parameterization. Unions are for the cases when you need the same block of memory to have multiple types, and are the least common in typical D code. Classes and structs are the backbone of user-defined types in D, and they have the most in common. The key difference is polymorphic inheritance; if you need it, you probably want a class. Otherwise, structs are lighter weight and give maximum flexibility. Using them, you can precisely define the layout of each byte with no hidden data, overload all operators, use deterministic destruction (the RAII idiom from C++), and use both reference or value semantics depending on your specific needs. D's structs also support a form of subtyping, though not virtual functions, which you'll see in Chapter 6, Wrapped Types.
Let's summarize as follows:

Since your vector type will not need virtual functions, it will be a struct.
How to do it…
Let's look at creating a vector type using the following steps:
- Declare the
struct
variable with a name. This declaration can appear anywhere; but, in your case, you want it to be generally accessible. So, it should go in the top-level scope of your module. Unlike C++, there is no need to put a semicolon at the end of thestruct
definition, as shown in the following code:struct Vector {}
- Determine which data members are needed and add them to the struct. Here, you need a magnitude and direction, and they will be floating point types:
struct Vector { float magnitude; float direction; }
- Add methods that operate on the data to the struct. In this case, you want to be able to add vectors together and convert from
(x, y)
coordinates. The complete code is as follows:struct Vector { // the data float magnitude; float direction; // the methods /// create a Vector from an (x, y) point static Vector fromPoint(float[2] point) { import std.math; Vector v; float x = point[0]; float y= point[1]; v.magnitude = sqrt(x ^^ 2 + y ^^ 2); v.direction = atan2(y, x); return v; }}} /// converts to an (x,y) point. returns in an array. float[2] toPoint() const { import std.math; float x = cos(direction) * magnitude; float y = sin(direction) * magnitude; return [x, y]; } /// the addition operator Vector opBinary(string op : "+")(Vector rhs) const { auto point = toPoint(), point2 = rhs.toPoint(); point[0] += point2[0]; point[1] += point2[1];];]; return Vector.fromPoint(point);); } }
- Use the new type as follows:
auto origin = Vector(0, 0); import std.math; auto result = origin + Vector(1.0, PI); import std.stdio; writeln("Vector result: ", result); writeln(" Point result: ", result.toPoint());
It will print Vector(1.0, 3.14)
and [-1, 0]
, showing the vector sum as magnitude and direction, and then x, y. Your run may have slightly different results printed due to differences in how your computer rounds off the floating point result.
How it works…
Structs are aggregate types that can contain data members and function methods. All members and methods are defined directly inside the struct, between the opening and closing braces. Data members have the same syntax as a variable declaration: a type (which can be inferred, if there is an initializer), a name, and optionally, an initializer. Initializers must be evaluated at compile time. When you declare a struct, without an explicit initializer, all members are set to the value of their initializers inside the struct
definition.
Methods have the same syntax as functions at module scope, with two differences; they can be declared static and they may have const
, immutable
, or inout
attached, which applies to the variable this
. The this
variable is an automatically declared variable that represents the current object instance in a method. The following recipe on immutability will discuss these keywords in more detail.
Operator overloading in D is done with methods and special names. In this section, you defined opBinary
, which lets you overload the binary operators such as the addition and subtraction operators. It is specialized only on the +
operator. It is also possible to overload casting, assignment, equality checking, and more.
At the usage point, you declared a vector with auto
, using the automatically defined constructor.
Finally, when you write the result, you use the automatic string formatting that prints the name and the values, in the same way as the automatic constructor. It is also possible to take control of this by implementing your own toString
method.
See also
- Chapter 6, Wrapped Types, will show more advanced capabilities, including how to use structs to make a reference type and to use constructors, destructors, postblits, and so on.
- Inheritance and dynamic class casting will show how to make the most of classes.
- Visit http://dlang.org/operatoroverloading.html for the language documentation on operator overloading. It details all the operators available for overloading and how to do it.
- 數(shù)據(jù)科學(xué)實戰(zhàn)手冊(R+Python)
- Hands-On Machine Learning with scikit:learn and Scientific Python Toolkits
- Cross-platform Desktop Application Development:Electron,Node,NW.js,and React
- Practical Data Science Cookbook(Second Edition)
- Selenium Design Patterns and Best Practices
- 深入理解Java7:核心技術(shù)與最佳實踐
- 假如C語言是我發(fā)明的:講給孩子聽的大師編程課
- Visual Basic程序設(shè)計習(xí)題解答與上機指導(dǎo)
- INSTANT Django 1.5 Application Development Starter
- 學(xué)習(xí)OpenCV 4:基于Python的算法實戰(zhàn)
- Vue.js應(yīng)用測試
- Orchestrating Docker
- 從Excel到Python數(shù)據(jù)分析:Pandas、xlwings、openpyxl、Matplotlib的交互與應(yīng)用
- Web編程基礎(chǔ):HTML5、CSS3、JavaScript(第2版)
- 例解Python:Python編程快速入門踐行指南