Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Жизнь без generics
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Alexey Palazhchenko
July 24, 2014
Programming
290
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Жизнь без generics
Alexey Palazhchenko
July 24, 2014
More Decks by Alexey Palazhchenko
See All by Alexey Palazhchenko
Using PostgreSQL's Background Worker Processes For Fun and Profit
aleksi
0
200
Песнь Хорьков и Гоферов
aleksi
0
400
Fuzzy generics
aleksi
0
200
On Ferrets and Gophers
aleksi
0
290
How to Go Wrong with Concurrency
aleksi
2
810
Adding context to existing code
aleksi
1
180
Зачем и как написать свой database/sql драйвер
aleksi
1
220
Cooking gRPC
aleksi
1
930
Profiling and Optimizing Go Programs
aleksi
1
1.8k
Other Decks in Programming
See All in Programming
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
9.2k
yield再入門 #phpcon
o0h
PRO
0
630
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.9k
Foundation Models frameworkで画像分析
ryodeveloper
1
120
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
130
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
210
共通化で考えるべきは、実装より公開する型だった
codeegg
0
250
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
140
Prismを使った型安全な暗号化_関数型まつり2026
_fhhmm
0
140
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
150
自作OSでスライド発表する
uyuki234
1
3.9k
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
360
Featured
See All Featured
Technical Leadership for Architectural Decision Making
baasie
3
440
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
A Modern Web Designer's Workflow
chriscoyier
698
190k
エンジニアに許された特別な時間の終わり
watany
108
250k
Amusing Abliteration
ianozsvald
1
230
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
420
The Cost Of JavaScript in 2023
addyosmani
55
10k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Between Models and Reality
mayunak
4
380
Git: the NoSQL Database
bkeepers
PRO
432
67k
Transcript
Жизнь без generics
Radio-T #399 http://www.radio-t.com
Контейнеры 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)
Свои контейнеры 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! }
Свои контейнеры 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! }
Свои контейнеры • builtin’ы особенные: new, make, append, copy, delete,
len, cap, close • range
Итого 1. Свои контейнеры нужно писать руками для каждого типа,
или использовать interface{}
Функциональный подход 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 })
Наследование и полиморфизм 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()! }
Наследование и полиморфизм Derived::F1()! Base::F2()! Derived::F3() Derived::F1()! Base::F2()! Base::F3()
Итого 1. Свои контейнеры нужно писать руками для каждого типа,
или использовать interface{} 2. Полиморфизма нет
Полиморфизм 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()! }
Полиморфизм 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))
Итого 1. Свои контейнеры нужно писать руками для каждого типа,
или использовать interface{} 2. Полиморфизма нет
Функциональный подход func Merge(! a map[_typeKey_]_typeValue_,! b map[_typeKey_]_typeValue_)
Свои контейнеры 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),! ! }! }
Свои контейнеры type StringIntMapTS struct {! ! l sync.RWMutex! !
data map[string]int! }! ! func NewStringIntMapTS(cap int) *StringIntMapTS {! ! return &StringIntMapTS{! ! ! data: make(map[string]int, cap),! ! }! }
gogen https://github.com/AlekSi/gogen! https://github.com/AlekSi/gogen-library
Итого 1. Свои контейнеры нужно писать руками для каждого типа,
или использовать interface{} 2. Полиморфизма нет
! ! ! ! ! ! https://github.com/AlekSi/gogen! https://github.com/AlekSi/gogen-library