package main
import "fmt"
type User struct {
UserName string
Category string
Age int
}
func main() {
users := []User{
User{UserName: "Bryan", Category: "Human", Age: 33},
User{UserName: "Jane", Category: "Rocker", Age: 25},
User{UserName: "Nancy", Category: "Mother", Age: 40},
User{UserName: "Chris", Category: "Dude", Age: 19},
User{UserName: "Martha", Category: "Cook", Age: 52},
}
// подключаетесь к базе
db, _ := sql.Open(...)
defer db.Close()
for _, user := range users {
fmt.Println(user)
// делаете запрос в базу
db.Exec("INSERT INTO users (name, category, age) VALUES ($1, $2, $3)", user.UserName, user.Category, user.Age)
}
}
tx, _ := db.Begin() // начинаете транзакцию
for _, user := range users {
fmt.Println(user)
// делаете запрос в базу (тут уже не db, а tx.Exec)
tx.Exec("INSERT INTO users (name, category, age) VALUES ($1, $2, $3)", user.UserName, user.Category, user.Age)
}
tx.Commit() // завершаете транзакцию, данные сохраняются в базе
package main
import (
"fmt"
"time"
)
var c = make(chan int, 3)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for _, val := range data {
c <- val
}
}
func read() {
for {
val := <-c
fmt.Println("read:", val)
}
}
package main
import (
"fmt"
"time"
)
var c = make(chan *int)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for _, val := range data {
v := val
c <- &v
}
}
func read() {
for {
val := <-c
fmt.Println("read:", *val)
}
}
package main
import (
"fmt"
"time"
var c = make(chan *int, 5)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for i := range data {
c <- &data[i]
}
}
func read() {
for {
val := <-c
fmt.Println("read:", *val)
}
}
package main
import (
"fmt"
"time"
)
var c = make(chan *int, 5)
var data = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
func main() {
fmt.Println("Hello, playground")
go save()
go read()
time.Sleep(3 * time.Second)
}
func save() {
for _, val := range data {
c <- &val
fmt.Printf("write: %v\n", &val)
}
}
func read() {
for {
val := <-c
fmt.Println("read:", *val)
}
}
Hello, playground
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
write: 0xc000094000
...
func save() {
for _, val := range data {
v := val
c <- &v
fmt.Printf("write: %v\n", &v)
}
}
Hello, playground
write: 0xc000094000
write: 0xc000094010
write: 0xc000094018
write: 0xc000094020
write: 0xc000094028
write: 0xc000094030
func Process(device test123.Command) {
device.Open()
device.Close()
}
dev1 := a123.A123struct{параметры...}
Process(dev1)
dev2 := b123.B123struct{параметры...}
Process(dev2)
// или с перечислением
devices := []test123.Command{dev1, dev2}
for _, device := range devices {
Process(device)
}
package main
import (
"fmt"
"os"
)
// Logger интерфейс логгера.
type Logger interface {
Error(msg string)
}
// StdoutLogger реализация интерфейса Logger для вывода сообщений в консоль.
type StdoutLogger struct{}
// NewStdoutLogger конструктор (возвращаем структуру, не интерфейс)
func NewStdoutLogger() *StdoutLogger {
return &StdoutLogger{}
}
// Error добавляет в лог сообщение с уровнем error
func (l *StdoutLogger) Error(msg string) {
fmt.Printf("ERROR: %s\n", msg)
}
// FileLogger реализация интерфейса Logger для вывода сообщений в файл.
type FileLogger struct {
FileName string
Fh *os.File
}
// NewFileLogger конструктор.
func NewFileLogger(fileName string) *FileLogger {
logger := &FileLogger{
FileName: fileName,
}
fh, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0664)
if err != nil {
panic(fmt.Sprintf("FileLogger: can't open log file: %s: %s\n", fileName, err))
}
logger.Fh = fh
return logger
}
// Error добавляет в лог сообщение с уровнем error.
func (l *FileLogger) Error(msg string) {
l.Fh.WriteString(fmt.Sprintf("ERROR: %s\n", msg))
}
// ProcessData какая то функция, которая использует логгер и которую не должна беспокоить реализация логгера.
// Тут тип параметра должен быть интерфейс.
func ProcessData(logger Logger) {
logger.Error("Data process some error happened")
}
func main() {
var logger Logger
// если лог файл не указан - используем StdoutLogger, если указан - используем FileLogger
logFile := os.Getenv("LOG_FILE")
if logFile != `` {
logger = NewFileLogger(logFile)
} else {
logger = NewStdoutLogger()
}
ProcessData(logger)
}
go run main.go
вы увидите сообщение в консоли:ERROR: Data process some error happened
LOG_FILE=test.log go run main.go
export LOG_FILE=test.log
go run main.go
db.SetConnMaxIdleTime(0)
db.SetConnMaxLifetime(0)
db.SetMaxIdleConns(10)
db.SetMaxOpenConns(10)
psql -h 127.0.0.1 -p 5432 -U user_name database_name
mysql -h 127.0.0.1 -P 3307 -u user_name -p database_name
update_answer_id_start, err33 := db.Query(fmt.Sprintf("UPDATE `ucp` SET `closed` = '1' WHERE `id` = '%d'", res_trim_int))
defer update_answer_id_start.Close()
update_answer_id_start, err33 := db.Exec("UPDATE `ucp` SET `closed` = '1' WHERE `id` = ?", res_trim_int)
for res_select_list.Next(){
err18 := res_select_list.Scan(&ucp.Id, &ucp.Text)
if err18 != nil {
panic(err18)
}
str.WriteString("LIST QUESTION:\r\nID- " + strconv.Itoa(ucp.Id) + " TEXT- " + ucp.Text)
}
str.WriteString("LIST QUESTION:\r\n")
for res_select_list.Next(){
err18 := res_select_list.Scan(&ucp.Id, &ucp.Text)
if err18 != nil {
panic(err18)
}
str.WriteString("ID- " + strconv.Itoa(ucp.Id) + " TEXT- " + ucp.Text + "\r\n")
}
// makeslicecopy allocates a slice of "tolen" elements of type "et",
// then copies "fromlen" elements of type "et" into that new allocation from "from".
// makeslicecopy allocates a slice of "tolen" elements of type "et",
// then copies "fromlen" elements of type "et" into that new allocation from "from".
func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer {
var tomem, copymem uintptr
if uintptr(tolen) > uintptr(fromlen) {
var overflow bool
tomem, overflow = math.MulUintptr(et.size, uintptr(tolen))
if overflow || tomem > maxAlloc || tolen < 0 {
panicmakeslicelen()
}
copymem = et.size * uintptr(fromlen)
} else {
// fromlen is a known good length providing and equal or greater than tolen,
// thereby making tolen a good slice length too as from and to slices have the
// same element width.
tomem = et.size * uintptr(tolen)
copymem = tomem
}
var to unsafe.Pointer
if et.ptrdata == 0 {
to = mallocgc(tomem, nil, false)
if copymem < tomem {
memclrNoHeapPointers(add(to, copymem), tomem-copymem)
}
} else {
// Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
to = mallocgc(tomem, et, true)
if copymem > 0 && writeBarrier.enabled {
// Only shade the pointers in old.array since we know the destination slice to
// only contains nil pointers because it has been cleared during alloc.
bulkBarrierPreWriteSrcOnly(uintptr(to), uintptr(from), copymem)
}
}
if raceenabled {
callerpc := getcallerpc()
pc := funcPC(makeslicecopy)
racereadrangepc(from, copymem, callerpc, pc)
}
if msanenabled {
msanread(from, copymem)
}
memmove(to, from, copymem)
return to
}
package main
import (
"encoding/json"
"fmt"
"log"
)
type TemplateCategory struct {
ID int `json:"id"`
Name string `json:"name"`
}
type Template struct {
Name string `json:"name"`
CategoryInfo *TemplateCategory `json:"category_info"`
}
func (t *Template) UnmarshalJSON(b []byte) error {
var result map[string]interface{}
if err := json.Unmarshal(b, &result); err != nil {
return err
}
if t == nil {
t = &Template{}
}
t.Name, _ = result[`name`].(string)
categoryInfo, isMap := result[`category_info`].(map[string]interface{})
if isMap {
t.CategoryInfo = &TemplateCategory{}
t.CategoryInfo.ID, _ = categoryInfo[`id`].(int)
t.CategoryInfo.Name, _ = categoryInfo[`name`].(string)
}
return nil
}
func main() {
json1 := []byte(`{
"name": "Мой шаблон",
"category_info": {
"id": 109,
"name": "Тест"
}
}`)
json2 := []byte(`{
"name": "Мой шаблон",
"category_info": []
}`)
var data1 Template
err := json.Unmarshal(json1, &data1)
if err != nil {
log.Fatalf(`json1: %s`, err)
}
var data2 Template
err = json.Unmarshal(json2, &data2)
if err != nil {
log.Fatalf(`json2: %s`, err)
}
fmt.Printf("data1: %+v\n", data1)
fmt.Printf("data1.CategoryInfo: %+v\n\n", data1.CategoryInfo)
fmt.Printf("\n\ndata2: %+v\n", data2)
fmt.Printf("data2.CategoryInfo: %+v\n\n", data2.CategoryInfo)
}
lp.MessageNew(func(_ context.Context, obj events.MessageNewObject) {
// тут приходит новый запрос
if obj.Message.Text == "/dump" {
var str strings.Builder
// читаете данные из базы
res, err := db.Query("SELECT `report_id`, `content_type` FROM `xf_report` WHERE `report_state` = 'open'")
// по одном их обрабатываете и записываете в strings.Builder
for res.Next(){
err := res.Scan(&report.Report_id, &report.Content_type)
str.WriteString(...)
}
// тут у вас все данные собраны в str
// отправляете данные в ответ
send, err2 := vk.MessagesSend(api.Params{
"peer_id": 2000000001,
"random_id": 0,
"message": str.String(),
})
}
SELECT * FROM schema_migrations;
+---------+-------+
| version | dirty |
+---------+-------+
| 1 | 1 |
+---------+-------+
1 row in set (0.00 sec)
migrate -path $PATH_TO_YOUR_MIGRATIONS -database $YOUR_DATABASE_URL force $VERSION
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract YourContractName is ERC20{
address owner;
constructor() ERC20("Your token name", "YourSymbol") {
// запоминаем кошелёк, который загружал токен, чтобы только он мог допечатывать деньги
owner = msg.sender;
}
function printCoins(uint256 amount) public {
require(msg.sender == owner, "Forbidden");
_mint(owner, amount); // зачисляем деньги на кошелёк владельца контракта
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract ACL {
// тут храним кошельки, которые могут выдавать/отзывать полномочия админа.
mapping (address => bool) public admins;
// тут те, кому разрешен доступ
mapping (address => bool) public accessGranted;
constructor() {
// наделяем полномочиями админа того, кто деплоил контракт чтобы он потом мог выдать полномочия кому-то еще.
admins[msg.sender] = true;
}
function grantAdmin(address to) public {
require(admins[msg.sender] == true, "Forbidden");
admins[to] = true;
}
function revokeAdmin(address to) public {
require(admins[msg.sender] == true, "Forbidden");
delete admins[to];
}
function grantAccess(address to) public {
require(admins[msg.sender] == true, "Forbidden");
accessGranted[to] = true;
}
function revokeAccess(address to) public {
require(admins[msg.sender] == true, "Forbidden");
delete accessGranted[to];
}
// эта функция доступна всем
function publicOK() public pure returns (string memory) {
return "public OK";
}
// эта доступна только тем, кому был предоставлен доступ
function protectedOK() public view returns (string memory) {
require(accessGranted[msg.sender] == true, "Forbidden");
return "protected OK";
}
}
usersQuerySvc := usersservices.NewQuerySvc(usersRepo, ...)
usersSignupSvc := usersservices.NewSignupSvc(usersQuerySvc, usersCommandSvc)
// например сервис для админов (с проверкой полномочий), методы которого уже можно использовать в endpoint'ax
usersAdminSvc := usersservices.NewAdminSvc(usersQuerySvc, usersCommandSvc)
projectSvc := projectservices.New(usersQuerySvc)
func main() {
var mux = http.NewServeMux()
mux.HandleFunc("/", indexPage)
var serv = &http.Server{
// добавляете параметр
Handler: mux,
Addr: serverPort,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
}
// вызываете с двумя параметрами
log.Fatal(serv.ListenAndServeTLS(TLScert, TLSkey))
}
package main
import (
"io"
"log"
"os"
"path/filepath"
)
type BlobReader struct {
keys []string
currentKey uint64
reader io.ReadCloser
}
func NewBlobReader(keys []string) *BlobReader {
return &BlobReader{
keys: keys,
}
}
// Read реализация интерфейса io.Reader, чтобы можно было ваш reader использовать в io.Copy
func (br *BlobReader) Read(p []byte) (int, error) {
var err error
// открываем каждый файл по очереди
if br.reader == nil {
filePath := filepath.Join(".", "blobs", br.keys[br.currentKey])
br.reader, err = os.Open(filePath)
if err != nil {
return 0, err
}
}
// читаем данные из текущего открытого файла, пока данные не закончатся
n, err := br.reader.Read(p)
// если данные в файле закончились, закрываем его
if err == io.EOF {
br.currentKey++
br.reader.Close()
br.reader = nil
// io.EOF в err должно вернуть только у последнего файла, чтобы io.Copy считал все файлы и не завис на последнем.
if br.currentKey < uint64(len(br.keys)) {
err = nil
}
}
return n, err
}
func main() {
blobReader := NewBlobReader([]string{
"2050-part1",
"2050-part2",
"2050-part3",
})
_, err := io.Copy(os.Stdout, blobReader)
if err != nil {
log.Fatalln(err)
}
log.Println("Done")
}
package main
import (
"context"
"fmt"
"sync"
)
func worker(ctx context.Context, worderID int, data chan int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("worker %d started\n", worderID)
for {
fmt.Printf("worker %d enter for\n", worderID)
select {
case <-ctx.Done():
fmt.Printf("worker %d cancelled\n", worderID)
return
case v, ok := <-data:
fmt.Printf("worker %d got data: %v, ok: %v\n", worderID, v, ok)
if !ok {
fmt.Printf("worker %d data channel was closed\n", worderID)
return
}
}
}
}
func main() {
var wg sync.WaitGroup
ctx, cancel := context.WithCancel(context.Background())
channels := make([]chan int, 10)
for i := 0; i < 10; i++ {
wg.Add(1)
channels[i] = make(chan int)
go worker(ctx, i, channels[i], &wg)
}
for i := 0; i < 10; i++ {
channels[i] <- i
}
cancel()
wg.Wait()
}
package main
import "fmt"
// объявляем интерфейс
type Profile interface {
GetFullName() string
}
// структура данных, которая будет реализовывать интерфейс Profile
type User struct {
Name string
LastName string
}
// реализация метода интерфейса Profile
func (u User) GetFullName() string {
return u.Name + ` ` + u.LastName
}
// пример функции, которая извлекает/формирует данные и возвращает слайс интерфейсов
func getProfiles() []Profile {
// создаём слайс интерфейсов
var result = make([]Profile, 10)
for i := 0; i<10; i++ {
// но заполняем слайс структурами, которые реализуют этот интерфейс
result[i] = User{
Name: fmt.Sprintf("Name%d", i),
LastName: fmt.Sprintf("LastName%d", i),
}
}
return result
}
// пример функции, которая работает со слайсом интерфейсов.
func printProfiles(profiles []Profile) {
for _, profile := range profiles {
fmt.Println(profile.GetFullName())
}
}
func main() {
printProfiles(getProfiles())
}