Static class method in go language - oop

I am looking at the example code at: https://golang.org/pkg/net/rpc/
type Arith int
func (t *Arith) Multiply(args *Args, reply *int) error {
*reply = args.A * args.B
return nil
}
From an OOP perspective, Multiply seems like a static method which doesn't access any data in Arith class; as the variable t is not used. Does it mean that int in type Arith int does not have any significance?

This doesn't have anything to do with OOP, it's simply that the rpc package's convention works by exporting methods from an "object" (with object here meaning any value with a non-empty method set)
The int is significant as the type of Arith, but it's not significant in this particular example, since the receiver is never referenced in the methods.
So yes, this example is kind of like a static class, but try not to map Java OOP ideas to Go, because Go is very different, as there are no "classes" or inheritance.

Another way to call simulating an static method, despite the fact it isn't, is as follows:
package main
import "fmt"
type Arith struct {
}
func (Arith) Multiply(a float32, b float32) float32 {
return a * b
}
func main() {
result := (Arith).Multiply(Arith{}, 15, 25)
fmt.Println(result)
}
But from my point of view, it is less understandable than placing this method in a separate package arith outside from class Arith

Related

What is the best way to refer to a static method from another static method of the same class in Rust?

In a new Rust module, I can write:
struct myStruct {
x : u32
}
impl myStruct {
fn new() -> myStruct{
myStruct{ x : other()}
}
fn other() -> u32 {
6
}
}
Coming from other OO languages, I would expect other() to be in scope for new(). That is, I would expect to be able to call one static method of a class from another static method of the same class. However, rustc produces the message:
error[E0425]: cannot find function `other` in this scope
--> dummy_module.rs:9:23
|
9 | myStruct{ x : other()}
| ^^^^^ not found in this scope
In contrast, the following Java code compiles fine:
public class myStruct{
int x;
public myStruct(){
x = other();
}
private int other(){
return 5;
}
}
I don't recall seeing any mention of this in the Rust book I'm using, and I can't seem to find a clear answer online. I can fix it by explicitly scoping the call to other with myStruct::other(), but this seems cumbersome. If I try use myStruct, then I get the cryptic message
7 | use myStruct;
| ^^^ unexpected token
Is this explicit scoping always required? If so, why?
Am I doing something incorrect? Is there an idiomatic workaround to this?
The Rust designers have made the following choice: everything related to the scope is explicit. So, just as you must type self to call a member function from another member function: self.foo(), you must call a static member with Self: Self::bar().
I think that it is the case because self could not be implicit: indeed it had to be added as a parameter either by value or borrowed, unlike in Java where this is always taken by value. Thus, because self was already an explicit parameter, it was needed as an explicit caller for consistency.
Because of its memory model, Rust expliciteness permit to give better error messages. For example, consider this code:
struct Struct;
impl Struct {
fn foo(&mut self) {
self.consume();
}
fn consume(self) {}
}
The error message is:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:5:9
|
5 | self.consume();
| ^^^^ cannot move out of borrowed content
Then the team made the choice of full expliciteness to maintain the grammar coherent.
Yes it is intended, because rust is not Java ;)
You just can write:
myStruct { x: myStruct::other() }
or
myStruct { x: Self::other() }
I can't tell you the exact design decision, why Self functions are not imported automatically, but you can "work-around" this, by using the correct path.

Does fragile base class issue exist in Go?

Despite using composition over inheritance?
If so, is there any solution for it at the language level?
As VonC wrote, but I'd like to point out something.
The fragile base class problem is often blamed on virtual methods (dynamic dispatch of methods – this means if methods can be overridden, the actual implementation that has to be called in case of such an overridden method can only be decided at runtime).
Why is this a problem? You have a class, you add some methods to it, and if MethodA() calls MethodB(), you can't have any guarantee that the MethodB() you wrote will be called and not some other method of a subclass that overrides your MethodB().
In Go there is embedding, but there is no polymorphism. If you embed a type in a struct, all the methods of the embedded type get promoted and will be in the method set of the wrapper struct type. But you can't "override" the promoted methods. Sure, you can add your own method with the same name, and calling a method by that name on the wrapper struct will invoke your method, but if this method is called from the embedded type, that will not be dispatched to your method, it will still call the "original" method that was defined to the embedded type.
So because of this, I'd say the fragile base class problem is only present in a quite mitigated form in Go.
Example
Demonstrating the problem in Java
Let's see an example. First in Java, because Java "suffers" from this kind of problem. Let's create a simple Counter class and a MyCounter subclass:
class Counter {
int value;
void inc() {
value++;
}
void incBy(int n) {
value += n;
}
}
class MyCounter extends Counter {
void inc() {
incBy(1);
}
}
Instantiating and using MyCounter:
MyCounter m = new MyCounter();
m.inc();
System.out.println(m.value);
m.incBy(2);
System.out.println(m.value);
The output is as expected:
1
3
So far so good. Now if the base class, Counter.incBy() would be changed to this:
void incBy(int n) {
for (; n > 0; n--) {
inc();
}
}
The base class Counter still remains flawless and operational. But the MyCounter becomes malfunctioning: MyCounter.inc() calls Counter.incBy(), which calls inc() but due to dynamic dispatch, it will call MyCounter.inc()... yes... endless loop. Stack overflow error.
Demonstrating the lack of the problem in Go
Now let's see the same example, this time written in Go:
type Counter struct {
value int
}
func (c *Counter) Inc() {
c.value++
}
func (c *Counter) IncBy(n int) {
c.value += n
}
type MyCounter struct {
Counter
}
func (m *MyCounter) Inc() {
m.IncBy(1)
}
Testing it:
m := &MyCounter{}
m.Inc()
fmt.Println(m.value)
m.IncBy(2)
fmt.Println(m.value)
Output is as expected (try it on the Go Playground):
1
3
Now let's change Counter.Inc() the same way we did in the Java example:
func (c *Counter) IncBy(n int) {
for ; n > 0; n-- {
c.Inc()
}
}
It runs perfectly, the output is the same. Try it on the Go Playground.
What happens here is that MyCounter.Inc() will call Counter.IncBy() which will call Inc(), but this Inc() will be Counter.Inc(), so no endless loop here. Counter doesn't even know about MyCounter, it does not have any reference to the embedder MyCounter value.
The Fragile base class problem is when a seemingly safe modifications to a base class, when inherited by the derived classes, may cause the derived classes to malfunction.
As mentioned in this tutorial:
For all intents and purposes, composition by embedding an anonymous type is equivalent to implementation inheritance. An embedded struct is just as fragile as a base class.

Kotlin: What can I do when a Java library has an overload of both primitive and boxed type?

For example, FastUtil's IntArrayList has a push method that accepts both int (primitive) and Integer (boxed), but Kotlin sees these both as the same function push(Int), therefore I cannot use the function at all as the function is ambiguous.
What should I do when a Java library has overloads for both the primitive and boxed type?
(p.s. I am aware that I can use the add(int) method. I am in search of what to do if I come across such a problem in the future.)
Consider these methods in Java:
void f(int x) { }
void f(Integer y) { }
In Kotlin, they are seen as
f(x: Int)
f(x: Int!)
The second method has a parameter of platform type, meaning it might be nullable, corresponding to Integer.
First one can be simply called with Kotlin Int passed:
f(5) // calls f(int x)
To call the second one, you can cast the argument to nullable Int?, thus selecting the overload:
f(5 as Int?) // calls f(Integer y)
Have you tried writing a Java class to serve as an intermediary? That is, write your own java class with the method you want Kotlin to see, then call that method from your Kotlin code.

Access method of extended type in Go

The follow codes produces "prog.go:17: c.Test undefined (type Child has no field or method Test)". (http://play.golang.org/p/g3InujEX9W)
package main
import "fmt"
type Base struct {
X int
}
func (b Base) Test() int {
return b.X
}
type Child Base
func main() {
c := Child{4}
fmt.Println(c.Test())
}
I realize Test is technically defined on Base, but should Child inherit that method?
the way to go for inheritance in go is using struct embedding with anonymous struct members.
Here is an adaption of your example.
Read about struct embedding and go's approach to inheritance etc here
The behaviour you encountered is expected and in sync with the golang specification, which explicitly states that:
The method set of any type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set.

Constructors in Go

I have a struct and I would like it to be initialised with some sensible default values.
Typically, the thing to do here is to use a constructor but since go isn't really OOP in the traditional sense these aren't true objects and it has no constructors.
I have noticed the init method but that is at the package level. Is there something else similar that can be used at the struct level?
If not what is the accepted best practice for this type of thing in Go?
There are some equivalents of constructors for when the zero values can't make sensible default values or for when some parameter is necessary for the struct initialization.
Supposing you have a struct like this :
type Thing struct {
Name string
Num int
}
then, if the zero values aren't fitting, you would typically construct an instance with a NewThing function returning a pointer :
func NewThing(someParameter string) *Thing {
p := new(Thing)
p.Name = someParameter
p.Num = 33 // <- a very sensible default value
return p
}
When your struct is simple enough, you can use this condensed construct :
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33}
}
If you don't want to return a pointer, then a practice is to call the function makeThing instead of NewThing :
func makeThing(name string) Thing {
return Thing{name, 33}
}
Reference : Allocation with new in Effective Go.
There are actually two accepted best practices:
Make the zero value of your struct a sensible default. (While this looks strange to most people coming from "traditional" oop it often works and is really convenient).
Provide a function func New() YourTyp or if you have several such types in your package functions func NewYourType1() YourType1 and so on.
Document if a zero value of your type is usable or not (in which case it has to be set up by one of the New... functions. (For the "traditionalist" oops: Someone who does not read the documentation won't be able to use your types properly, even if he cannot create objects in undefined states.)
Go has objects. Objects can have constructors (although not automatic constructors). And finally, Go is an OOP language (data types have methods attached, but admittedly there are endless definitions of what OOP is.)
Nevertheless, the accepted best practice is to write zero or more constructors for your types.
As #dystroy posted his answer before I finished this answer, let me just add an alternative version of his example constructor, which I would probably write instead as:
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33} // <- 33: a very sensible default value
}
The reason I want to show you this version is that pretty often "inline" literals can be used instead of a "constructor" call.
a := NewThing("foo")
b := &Thing{"foo", 33}
Now *a == *b.
There are no default constructors in Go, but you can declare methods for any type. You could make it a habit to declare a method called "Init". Not sure if how this relates to best practices, but it helps keep names short without loosing clarity.
package main
import "fmt"
type Thing struct {
Name string
Num int
}
func (t *Thing) Init(name string, num int) {
t.Name = name
t.Num = num
}
func main() {
t := new(Thing)
t.Init("Hello", 5)
fmt.Printf("%s: %d\n", t.Name, t.Num)
}
The result is:
Hello: 5
I like the explanation from this blog post:
The function New is a Go convention for packages that create a core type or different types for use by the application developer. Look at how New is defined and implemented in log.go, bufio.go and cypto.go:
log.go
// New creates a new Logger. The out variable sets the
// destination to which log data will be written.
// The prefix appears at the beginning of each generated log line.
// The flag argument defines the logging properties.
func New(out io.Writer, prefix string, flag int) * Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
bufio.go
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) * Reader {
return NewReaderSize(rd, defaultBufSize)
}
crypto.go
// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
panic("crypto: requested hash function is unavailable")
}
Since each package acts as a namespace, every package can have their own version of New. In bufio.go multiple types can be created, so there is no standalone New function. Here you will find functions like NewReader and NewWriter.
In Go, a constructor can be implemented using a function that returns a pointer to a modified structure.
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
For weak dependencies and better abstraction, the constructor does not return a pointer to a structure, but an interface that this structure implements.
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}
another way is;
package person
type Person struct {
Name string
Old int
}
func New(name string, old int) *Person {
// set only specific field value with field key
return &Person{
Name: name,
}
}
If you want to force the factory function usage, name your struct (your class) with the first character in lowercase. Then, it won't be possible to instantiate directly the struct, the factory method will be required.
This visibility based on first character lower/upper case work also for struct field and for the function/method. If you don't want to allow external access, use lower case.
Golang is not OOP language in its official documents.
All fields of Golang struct has a determined value(not like c/c++), so constructor function is not so necessary as cpp.
If you need assign some fields some special values, use factory functions.
Golang's community suggest New.. pattern names.
I am new to go. I have a pattern taken from other languages, that have constructors. And will work in go.
Create an init method.
Make the init method an (object) once routine. It only runs the first time it is called (per object).
func (d *my_struct) Init (){
//once
if !d.is_inited {
d.is_inited = true
d.value1 = 7
d.value2 = 6
}
}
Call init at the top of every method of this class.
This pattern is also useful, when you need late initialisation (constructor is too early).
Advantages: it hides all the complexity in the class, clients don't need to do anything.
Disadvantages: you must remember to call Init at the top of every method of the class.