package main
func main() {
var str strType
str.Temp()
}
type strType string
func (s strType) Temp() {
}
package main
import (
"fmt"
"sync"
)
type Task struct {
URL string
// сюда можно еще добавить нужные данные для задачи
}
type Result struct {
// если нам нужно что-то получать как результат обработки задачи
// то можно результат класть сюда
}
const (
workersCount = 5
)
func main() {
tasks := make(chan Task)
results := make(chan Result)
go generateTasks(tasks)
wg := &sync.WaitGroup{}
for i := 0; i < workersCount; i++ {
wg.Add(1) // обязательно инкрементим вне воркера, потому что воркер стартует не сразу
go worker(tasks, results, wg)
}
go func() {
wg.Wait()
// wg.Wait пустит нас сюда только когда все воркеры завершатся
// а значит, нам можно закрывать канал результатов, потому что результатов больше точно не будет
close(results)
}()
for result := range results {
// обрабатываем результаты, если нужно
// если нам не нужно централизованное место для обработки результатов,
// канал results и все, что с ним связано, можно убрать
fmt.Println("got result:", result)
}
// программа завершится как только канал results будет закрыт
}
func generateTasks(tasks chan<- Task) { // тип chan<- значит, что в переданный сюда канал можно только писать, нельзя читать
// тут генерируем наши задачи, читаем их из файла, например
for i := 0; i < 20; i++ {
tasks <- Task{
URL: fmt.Sprintf("http://test.com?i=%d", i),
}
}
// как только задачи закончились, закрываем канал
// этим мы сигнализируем воркерам, что работы больше нет, можно завершаться
close(tasks)
}
func worker(tasks <-chan Task, results chan<- Result, wg *sync.WaitGroup) {
defer wg.Done() // defer позволяет точно не забыть сделать Done() при завершении функции
for task := range tasks {
fmt.Println(task.URL)
var res Result
// здесь пишем код, который обрабатывает задачу
// генерируем на выходе какой-то результат (если результат нам не нужен, можем это опустить)
results <- res
}
}
package main
import (
"bufio"
"fmt"
"os"
"sync"
)
func main() {
urls := make(chan string)
go fillChannel(urls)
// создаем группу для ожидания, того, что все воркеры завершены
wg := &sync.WaitGroup{}
for i := 0; i < 5; i++ {
// при запуске каждого воркера, увеличиваем счетчик в группе на 1
wg.Add(1)
go requestWorker(urls, wg)
}
// ждем, пока счетчик в группе не будет равен 0
wg.Wait()
}
func requestWorker(channel <-chan string, wg *sync.WaitGroup) {
// По завершении воркера счетчик в группе будет уменьшен на 1
defer wg.Done()
// Заодно пишем сообщение о завершении воркера
defer println("Worker stopped")
// Постоянно читаем из канала новые сообщения
// цикл автоматически завершится, когда канал закроется и буфер будет пуст
for url := range channel {
println(url)
}
}
func fillChannel(channel chan<- string) {
file, err := os.Open("data.txt")
defer file.Close()
if err != nil {
fmt.Println(err)
return
}
fileScanner := bufio.NewScanner(file)
fileScanner.Split(bufio.ScanLines)
for fileScanner.Scan() {
channel <- fileScanner.Text()
}
// закрываем канал, когда данные кончились
// в го принято, чтобы канал закрывал только тот, кто в него пишет
close(channel)
}
cmd := exec.Command("python", "script.py")
stdoutBuf := bytes.NewBuffer(nil)
cmd.Stdout = stdoutBuf
if err := cmd.Run(); err != nil {
log.Println(err.Error())
}
fmt.Println(stdoutBuf.String())
cmd := exec.Command("python", "script.py")
res, err := cmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(res))
add 2
, тогда мы применим только первый аргумент функции. Когда мы так делаем, на выходе получаем функцию с одним аргументом, потому что первый аргумент уже равен 2. Можете считать, что он просто сохранен внутри этой функции, чтобы быть использованным, когда функция будет полностью применена.Что вообще происходит в теле возвращаемой функции?
func main() {
fmt.Println(sum(1, 2))
carried := carry(sum, 1)
fmt.Println(carried(2))
}
func sum(a, b int) int {
return a + b
}
func carry(fn func(int, int) int, a int) func(int) int {
return func(b int) int {
return fn(a, b)
}
}
package main
import (
"fmt"
"log"
)
func main() {
code := map[string]interface{}{
"test": "test",
}
// извлекаем interface{} из мапы внутри которого строка
ifaceStr := code["test"]
// извлекаем строку из interface{}
str, ok := ifaceStr.(string)
if !ok {
log.Fatal("it's not a string")
}
fmt.Println(str)
}
r.Handler("GET", "/", fServer)
r.Handler("GET", "/*filepath", fServer)
main redeclared in this block {строка 8 столбец 6 }
previous declaration at ./hello.go:18:6