Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Жизнь без generics

Жизнь без generics

4618c5e97c59abd315cc2d7dc809f8c8?s=128

Alexey Palazhchenko

July 24, 2014
Tweet

Transcript

  1. Жизнь без generics

  2. Radio-T #399 http://www.radio-t.com

  3. Контейнеры m := make(map[string]int)! m["answer"] = 42! if len(m) >

    0 {! ! delete(m, "answer")! }! ! func make(Type, size IntegerType) Type! func len(v Type) int! func delete(m map[Type]Type1, key Type)
  4. Свои контейнеры type StringIntMapTS struct {! ! l sync.RWMutex! !

    data map[string]int! }! ! func NewStringIntMapTS(cap int) *StringIntMapTS {! ! return &StringIntMapTS{! ! ! data: make(map[string]int, cap),! ! }! }! ! func (m *StringIntMapTS) Len() int {! ! m.l.RLock()! ! l := len(m.data)! ! m.l.RUnlock()! ! return l! }! ! func (m *StringIntMapTS) Get(key string) (v int, k bool) {! ! m.l.RLock()! ! value, ok = m.data[key]! ! m.l.RUnlock()! ! return! }
  5. Свои контейнеры type MapTS struct {! ! l sync.RWMutex! !

    data map[interface{}]interface{}! }! ! func NewMapTS(cap int) *MapTS {! ! return &MapTS{! ! ! data: make(map[interface{}]interface{}, cap),! ! }! }! ! func (m *MapTS) Len() int {! ! m.l.RLock()! ! l := len(m.data)! ! m.l.RUnlock()! ! return l! }! ! func (m *MapTS) Get(key interface{}) (v interface{}, k bool) {! ! m.l.RLock()! ! value, ok = m.data[key]! ! m.l.RUnlock()! ! return! }
  6. Свои контейнеры • builtin’ы особенные: new, make, append, copy, delete,

    len, cap, close • range
  7. Итого 1. Свои контейнеры нужно писать руками для каждого типа,

    или использовать interface{}
  8. Функциональный подход type Thing struct {! ! F int! }!

    ! type Things []Thing! ! myThings := &Things{...}! myThings = Where(myThings, func(t *Thing) { t.F > 42 })! myThings = SortBy(myThings, func(a, b *Thing) bool { return a.F < b.F })
  9. Наследование и полиморфизм class Base! {! public:! ! virtual void

    F2() {! ! ! printf("Base::F2()\n");! ! ! this->F3();! ! }! ! virtual void F3() {! ! ! printf("Base::F3()\n");! ! }! };! ! class Derived : public Base! {! public:! ! virtual void F1() {! ! ! printf("Derived::F1()\n");! ! ! this->F2();! ! }! ! virtual void F3() {! ! ! printf("Derived::F3()\n");! ! }! };! ! int main()! {! ! (new Derived)->F1();! } type Base struct{}! ! func (this *Base) F2() {! ! println("Base::F2()")! ! this.F3()! }! ! func (this *Base) F3() {! ! println("Base::F3()")! }! ! type Derived struct {! ! Base! }! ! func (this *Derived) F1() {! ! println("Derived::F1()")! ! this.F2()! }! ! func (this *Derived) F3() {! ! println("Derived::F3()")! }! ! func main() {! ! new(Derived).F1()! }
  10. Наследование и полиморфизм Derived::F1()! Base::F2()! Derived::F3() Derived::F1()! Base::F2()! Base::F3()

  11. Итого 1. Свои контейнеры нужно писать руками для каждого типа,

    или использовать interface{} 2. Полиморфизма нет
  12. Полиморфизм type F3er interface {! ! F3()! }! ! type

    Base struct {! ! F3er F3er! }! ! func (this *Base) F2() {! ! println("Base::F2()")! ! this.F3er.F3()! }! ! func (this *Base) F3() {! ! println("Base::F3()")! } type Derived struct {! ! Base! }! ! func (this *Derived) F1() {! ! println("Derived::F1()")! ! this.F2()! }! ! func (this *Derived) F3() {! ! println("Derived::F3()")! }! ! func main() {! ! d := new(Derived)! ! d.F3er = d! ! d.F1()! }
  13. Полиморфизм type Interface interface {! ! Len() int! ! Less(i,

    j int) bool! ! Swap(i, j int)! }! ! type ByAge []Person! func (a ByAge) Len() int { return len(a) }! func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }! func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }! ! sort.Sort(ByAge(people))
  14. Итого 1. Свои контейнеры нужно писать руками для каждого типа,

    или использовать interface{} 2. Полиморфизма нет
  15. Функциональный подход func Merge(! a map[_typeKey_]_typeValue_,! b map[_typeKey_]_typeValue_)

  16. Свои контейнеры type (! ! _typeKey_ string! ! _typeValue_ int!

    )! ! type _TypeKey__TypeValue_MapTS struct {! ! l sync.RWMutex! ! data map[_typeKey_]_typeValue_! }! ! func New_TypeKey__TypeValue_MapTS(cap int) *_TypeKey__TypeValue_MapTS {! ! return &_TypeKey__TypeValue_MapTS{! ! ! data: make(map[_typeKey_]_typeValue_, cap),! ! }! }
  17. Свои контейнеры type StringIntMapTS struct {! ! l sync.RWMutex! !

    data map[string]int! }! ! func NewStringIntMapTS(cap int) *StringIntMapTS {! ! return &StringIntMapTS{! ! ! data: make(map[string]int, cap),! ! }! }
  18. gogen https://github.com/AlekSi/gogen! https://github.com/AlekSi/gogen-library

  19. Итого 1. Свои контейнеры нужно писать руками для каждого типа,

    или использовать interface{} 2. Полиморфизма нет
  20. ! ! ! ! ! ! https://github.com/AlekSi/gogen! https://github.com/AlekSi/gogen-library