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
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
820
Adding context to existing code
aleksi
1
180
Зачем и как написать свой database/sql драйвер
aleksi
1
220
Cooking gRPC
aleksi
1
940
Profiling and Optimizing Go Programs
aleksi
1
1.8k
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
560
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
400
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
170
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
500
数百円から始めるRuby電子工作
tarosay
0
140
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
370
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
810
torikago - Ruby::Boxで照らすモジュラモノリスの実行境界
se4weed
1
360
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
110
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
490
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
4.3k
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
550
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
42
3.1k
The Language of Interfaces
destraynor
162
27k
How STYLIGHT went responsive
nonsquared
100
6.2k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Balancing Empowerment & Direction
lara
6
1.2k
Done Done
chrislema
186
16k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
270
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
340
How to build a perfect <img>
jonoalderson
1
5.9k
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