package main import "fmt" func main() { status := GetPlan(1) fmt.Println(status) } func GetPlan(id int) string { return [...]string{ "plan1", "plan2", "plan3", }[id-1] }
Рубрика: Golang
Server Sent Event (SSE) with Go
Source https://github.com/evgensr/sse
package main import ( "fmt" "net/http" "time" ) func main() { http.HandleFunc("/events", eventsHandler) http.ListenAndServe(":8080", nil) } func eventsHandler(w http.ResponseWriter, r *http.Request) { // Set CORS headers to allow all origins. You may want to restrict this to specific origins in a production environment. w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Expose-Headers", "Content-Type") w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") // Simulate sending events (you can replace this with real data) for i := 0; i < 10; i++ { fmt.Fprintf(w, "data: %s\n\n", fmt.Sprintf("Event %d", i)) time.Sleep(2 * time.Second) w.(http.Flusher).Flush() } // Simulate closing the connection closeNotify := w.(http.CloseNotifier).CloseNotify() <-closeNotify }
<!DOCTYPE html> <html> <head> <title>SSE Example</title> </head> <body> <div id="sse-data"></div> <script> const eventSource = new EventSource('http://localhost:8080/events'); eventSource.onmessage = function(event) { const dataElement = document.getElementById('sse-data'); dataElement.innerHTML += event.data + '<br>'; }; </script> </body> </html>
Оптимизация кода golang
Когда мы фильтруем фрагменты в Go, типичным решением является создание нового фрагмента для отфильтрованных элементов (var filtered []int).
Однако этот метод приводит к дополнительному выделению памяти, потому что мы создаём пустой слайс, и при каждом добавлении элемента нужно будет заново аллоцировать память.
Более разумным способом решения этой проблемы является такое создание filtered := numbers[:0]
Так мы создадим слайс с ёмкостью numbers и избегаем дополнительных выделений памяти в дальнейшем
В выражении numbers[:0]
, 0
указывает на индекс, до которого (не включая его) будут скопированы элементы из среза numbers
. По сути, это создает новый срез, который имеет ту же емкость, что и исходный срез numbers
, но не содержит никаких элементов.
Вот как это работает:
numbers[:]
создает копию срезаnumbers
, включая все его элементы.numbers[:n]
, гдеn
— это неотрицательное целое число, создает новый срез, который содержит первыеn
элементовnumbers
.numbers[:0]
создает новый срез, который не содержит элементов, но имеет ту же емкость, что иnumbers
. Это означает, что при добавлении элементов в срезfiltered
с помощью функцииappend
память будет выделена из исходного массива, который лежит в основе срезаnumbers
, до тех пор, пока не будет превышена его емкость.
Обновить все пакеты
go get -u ./...
Состоялся релиз Go 1.22
Состоялся релиз Go 1.22
Теперь range по int
for i := range 10 { println(i) }
Golang log
func logJson(data interface{}) string { bytes, err := json.Marshal(data) if err != nil { log.Fatal(err) } return string(bytes) }
func logJson(data interface{}) { bytes, err := json.Marshal(data) if err != nil { log.Fatal(err) } log.Println(string(bytes)) }
Anti-Spam Bot
Welcome to the Anti-Spam Bot project! This bot is designed to monitor and manage spam activities, ensuring smooth and uninterrupted conversations.
https://github.com/evgensr/anti-spam
Fixing For Loops in Go 1.22
Fixing For Loops in Go 1.22
https://go.dev/blog/loopvar-preview
David Chase и Russ Cox в официальном блоге Go рассказывают про проблему LoopVar (переменной цикла) и приводят конкретные примеры, в том числе из реального кейса проекта — Lets Encrypt.
Затем рассказывают, как именно эта проблема решается. Если кратко:
> change for loops to make these variables have per-iteration scope instead of per-loop scope
Как вы помните, эта фича уже есть в Go v1.21, но её нужно включить:
GOEXPERIMENT=loopvar go test
А в версии 1.22 она уже будет работать по-умолчанию
Получить курс доллара на forex
func forex() string { client := &http.Client{ Timeout: 10 * time.Second, } req, err := http.NewRequest("GET", "https://www.investing.com/currencies/usd-rub", nil) if err != nil { log.Fatal(err) } req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537") res, err := client.Do(req) if err != nil { log.Println(err) } defer res.Body.Close() if res.StatusCode != 200 { log.Printf("status code error: %d %s", res.StatusCode, res.Status) } // Load the HTML document doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { log.Println(err) } var price string doc.Find("span[data-test='instrument-price-last']").Each(func(index int, item *goquery.Selection) { price = item.Text() fmt.Println(price) }) return price }
Работа со строками в golang
package main import ( "fmt" "strings" ) func main() { fmt.Println( // true strings.Contains("test", "es"), // 2 strings.Count("test", "t"), // true strings.HasPrefix("test", "te"), // true strings.HasSuffix("test", "st"), // 1 strings.Index("test", "e"), // "a-b" strings.Join([]string{"a","b"}, "-"), // == "aaaaa" strings.Repeat("a", 5), // "bbaa" strings.Replace("aaaa", "a", "b", 2), // []string{"a","b","c","d","e"} strings.Split("a-b-c-d-e", "-"), // "test" strings.ToLower("TEST"), // "TEST" strings.ToUpper("test"), ) }