digitalmars.D.learn - What's the right way for doing this in D?
- Namespace (29/29) Aug 24 2013 I liked to know which of this two methods is more common to you,
- bearophile (9/11) Aug 24 2013 Both ways work. I usually prefer the first one because it's more
- Andrej Mitrovic (51/55) Aug 24 2013 Note also that UFCS can introduce the function hijacking protection.
I liked to know which of this two methods is more common to you, A or B: Method A: ---- import std.stdio; struct Vector2f { public: float x; float y; float dot(ref const Vector2f vec) const { return this.x * vec.x + this.y * vec.y; } } ---- Method B: ---- struct Vector2f { public: float x; float y; } float dot(ref const Vector2f lhs, ref const Vector2f rhs) { return lhs.x * rhs.x + lhs.y * rhs.y; } ---- Until now I used Method A, but because of UFCS and the fact, that the dot product doesn't affect the object, I thought about which way would make more sense. I still like Method A but I'm curious what you think.
Aug 24 2013
Namespace:I liked to know which of this two methods is more common to you, A or B:Both ways work. I usually prefer the first one because it's more DRY. I use external functions when I write functions that are meant to work on more different structs, or to reduce template bloat when a function works only on not templated values. Note that fields and methods are public on default in structs, so you don't need the "public:" tag. Bye, bearophile
Aug 24 2013
On 8/24/13, Namespace <rswhite4 googlemail.com> wrote:Until now I used Method A, but because of UFCS and the fact, that the dot product doesn't affect the object, I thought about which way would make more sense. I still like Method A but I'm curious what you think.Note also that UFCS can introduce the function hijacking protection. For example, if you have: ----- module a; import b; struct A { } void test(A a) { } void main() { B b; b.test(); } ----- ----- module b; struct B { } void test(B b) { } ----- This will result in: a.d(10): Error: function a.test (A a) is not callable using argument types (B) I tend to use UFCS when I need the function to handle multiple types - e.g. a templated function that should be used with UFCS, or when I want to add UFCS syntax to a type which I have no control over (e.g. a Phobos or 3rd party library type). Otherwise if your function is only ever going to be used with a single type you might as well put it as a member function, unless you prefer otherwise (e.g. some people dislike indentation). Btw, I thought UFCS might disable using the 'super' syntax, but to my surprise it actually works: ----- class A { } void foo(A a) { } class B : A { void test() { super.foo(); // ok } } void main() { } ----- Pretty cool. Finally a note about the documentation. If you put your functions as member functions, the documentation becomes part of the aggregate type that they're members of. So it might make the documentation easier to read.
Aug 24 2013