LINUX.ORG.RU

История изменений

Исправление kaldeon, (текущая версия) :

Писать в ОО стиле можно на C, но неудобно. Основная суть ОО стиля в современном понимании — это возможность привязать к данным функции, чтобы выбор функции был произведён как можно раньше, при создании переменной, а не в момент первого использования. В C это довольно неприятно делать вручную.

На поверхности этот код эквивалентен:

typedef struct Object Object;
void swap(Object *o) {}

type Object struct {}
func (o *Object) Swap() {}

В Го структура — это такая же структура как в C. При объявлении переменной в неё не записывается информация о привязанных функциях. Поэтому, в частности, мы не можем «динамично» заменить функцию:

// won’t compile
var o Object
o.Swap = func(Object *o) {}

То есть мы всё ещё работаем в обычной процедурной парадигме, легко переносимой на C. Суть ОО стиля в том, что мы можем заменить привязанные функции на раннем этапе.

В Go набор функций привязан к типу. Соответственно, изменив тип, мы можем изменить набор функций:

type FooObject Object
func (fo *FooObject) Swap() {}

var o Object
fo := FooObject(o)

И это ОО стиль.

(Другой, более распространённый способ — интерфейсы, которые позволяют забыть конкретные данные и оперировать чисто набором функций.)

Система типов C не сможет повторить приведённый пример. Поэтому его повторяют с помощью ручной работы — буквальным встраиванием функций в структуру, когда в структуре хранятся указатели на функции.

Исходная версия kaldeon, :

Писать в ОО стиле можно на C, но неудобно. Основная суть ОО стиля в современном понимании — это возможность привязать к данным функции, чтобы выбор функции был произведён как можно раньше, при создании переменной, а не в момент первого использования. В C это довольно неприятно делать вручную.

На поверхности этот код эквивалентен:

typedef struct Object Object;
void swap(Object *o) {}

type Object struct {}
func (o *Object) Swap() {}

В Го структура — это такая же структура как в C. При объявлении переменной в неё не записывается информация о привязанных функциях. Поэтому, в частности, мы не можем «динамично» заменить функцию:

// won’t compile
var o Object
o.Swap = func(Object *o) {}

То есть мы всё ещё работаем в обычной процедурной парадигме, легко переносимой на C. Суть ОО стиля в том, что мы можем заменить привязанные функции на раннем этапе.

В Go набор функций привязан к типу. Соответственно, изменив тип, мы можем изменить набор функций:

type FooObject Object
func (fo *FooObject) Swap() {}

var o Object
fo := FooObject(o)

Одна и та же структура, в которой мы поменяли набор функций просто поменяв тип. И это ОО стиль.

(Другой, более распространённый способ — интерфейсы, которые позволяют забыть конкретные данные и оперировать чисто набором функций.)

Система типов C не сможет повторить приведённый пример. Поэтому его повторяют с помощью ручной работы — буквальным встраиванием функций в структуру, когда в структуре хранятся указатели на функции.