Страницы

воскресенье, 10 февраля 2019 г.

Golang generics wanted

Вот уже несколько месяцев я пишу на Go и мне это нравится. Инструменты разработки просто супер. Visual Studio Code решает. Язык простойGo 2 в процессеМодули уже здесь, и судя по всему скоро станут еще лучше. Обработка ошибок после коллбэков не самое страшное. Сами по себе ошибки страшнее, но с помощью существующих сторонних решений можно как-то перетерпеть. А вот дженериков не хватает уже сейчас: дублировать код функций, создавать новые структуры там где нет никакой разницы какого типа аргумент или поле - занятие на любителя.


Например нужно безопасно закрыть канал.

Можно сделать так:
package main

import (
 "fmt"
 "sync"
)

func main() {
 var wg sync.WaitGroup

 ch := make(chan struct{})
 sch := &SafeStructChan{C: ch}
 i := 3
 wg.Add(i)
 for i > 0 {
  go func(i int) {
   fmt.Printf("%v closed %v\n", i, sch.SafeClose())
   wg.Done()
  }(i)
  i--
 }
 wg.Wait()
}

type SafeStructChan struct {
 C      chan struct{}
 closed bool
 mutex  sync.Mutex
}

func (ch *SafeStructChan) SafeClose() bool {
 ch.mutex.Lock()
 defer ch.mutex.Unlock()

 if ch.closed {
  return false
 }

 close(ch.C)
 ch.closed = true
 return true
}

Или даже так:
package main

import (
 "fmt"
 "sync"
)

func main() {
 var wg sync.WaitGroup

 ch := make(chan struct{})
 i := 3
 wg.Add(i)
 for i > 0 {
  go func(i int) {
   fmt.Printf("%v closed %v\n", i, SafeClose(ch))
   wg.Done()
  }(i)
  i--
 }
 wg.Wait()
}

func SafeClose(ch chan struct{}) (closed bool) {
 defer func() {
  if recover() != nil {
   closed = false
  }
 }()

 close(ch)
 return true
}

И потом все то же самое для chan int, chan boolchan os.Signal ... а хотелось бы один раз для chan T.

Комментариев нет:

Отправить комментарий

Комментарий будет опубликован после модерации