Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
ООП — это отнюдь не «классы» и «наследование»
Вот такие статьи по Go и нужны. Ничего против не скажешь.
Go и без привычного наследования является ООП языком, а структуры Go вообще не вижу причин не называть классами.Серьезно? Или вы спать будете плохо, если окажется что Go не объектно-ориентированный язык? Так вот, в Go нет ООП. В нем нет ни классов, ни наследования, ни прототипов, ни полиморфизма. Go – не объектно-ориентированный язык. Извините.
«Я придумал термин «объектно-ориентированный», и я уверяю вас, что не имел в виду C++».
Мне вот хочется называть его ООП, потому что таково мое мнение, я вижу концепции ООП в таком свете.Это такой шедевр, что я даже не знаю, что вам на это ответить. Вы точно правильно профессию выбрали? Вы инженер или литературный критик, чтобы использовать аргумент в стиле «я художник, я так вижу»?
cannot use T as MyIface… T does not implement MyIface (missing SomeMethod method)
var _ MyIface = (MyType)(nil)
func (c Circle) Square() int64 {
return (2 * c.Radius) ^ 2
}
package main
import (
"math"
"testing"
)
func TestCircle(t *testing.T) {
square := NewCircle(0, 0, 10).Square()
want := 100 * math.Pi
if square != want {
t.Fatalf("Want %v, but got %v", want, square)
}
}
type Figure interface {
...
AboutSquare() string
}
type Rectangle struct {
...
}
func (r RoundRectangle) Square() float64 {
return math.Abs(float64((r.Right - r.Left) * (r.Top - r.Bottom)))
}
func (r Rectangle) AboutSquare() string {
fmt.Sprintf("my square: %d", r.Square())
}
type RoundRectangle struct {
...
}
func (r RoundRectangle) Square() float64 {
circSquar := math.Pi * float64(r.Radius^2)
rectSquar := math.Abs(float64((r.Right - r.Left) * (r.Top - r.Bottom)))
return rectSquar - float64((r.Radius*2)^2) + circSquar
}
func newRoundRectangle(...) *RoundRectangle {
...
}
myRoundRectangle := newRoundRectangle(4, 4, 2)
fmt.Println(myRoundRectangle.AboutSquare()) // my square: 16
type Rectangle struct {
this *Figure
}
func newRoundRectangle(...) *RoundRectangle {
ret := return RoundRectangle{
...
}
ret.this = &ret
return &ret
}
func (r Rectangle) AboutSquare() string {
fmt.Sprintf("my square: %d", r.this.Square())
}
func AboutSquare(r Figure) string {
fmt.Sprintf("my square: %d", r.Square())
}
наследовать одну фигуру от другой — типичная ошибка ООП
Общее правило тут такое — если метод должен изменять значение c или если Circle — большущщая структура, занимающая много места в памяти — тогда использовать указатель. В остальных случаях, будет дешевле и эффективней передавать значение в качестве ресивера метода.
func NewRectangle(left, top, right, bottom int64) *Rectangle
Почему конструктор возвращает указатель на структуру?
Возвращать саму структуру, как я понимаю, значит лишний раз делать её копию без получения каких-либо плюсов.
хотя как понять насколько у меня «большущая структура»
If the receiver is a large struct or array, a pointer receiver is more efficient. How large is large? Assume it's equivalent to passing all its elements as arguments to the method. If that feels too large, it's also too large for the receiver.
как понять насколько у меня «большущая структура», что пора использовать указатель?
Пример решения типичной ООП задачи на языке Go