休闲游戏项目收获

79 阅读2分钟

第一个线上项目不足,应该学习的地方

ent的批量创建

names := []string{"pedro", "xabi", "layla"} 
bulk := make([]*ent.PetCreate, len(names)) 
for i, name := range names { 
    bulk[i]=client.Pet.Create().SetName(name).SetOwner(a8m)
} 
pets, err := client.Pet.CreateBulk(bulk...).Save(ctx)

判断切片中是否包含某元素

func ConvertStrSlice2Map(sl []string) map[string]struct{} {  
    set := make(map[string]struct{}, len(sl))  
    for _, v := range sl {  
        set[v] = struct{}{}  
    }  
    return set  
}  
func InStrMap(m map[string]struct{}, s string) bool {  
    _, ok := m[s]  
    return ok  
}  
  
func StrIfContain(str []string, s string) bool {  
    mp := ConvertStrSlice2Map(str)  
    return InStrMap(mp, s)  
}

相似结构体的转换


package main

import (
  "fmt"

  "github.com/jinzhu/copier"
)

type User struct {
  Name string
  Age  int
}

type Employee struct {
  Name string
  Age  int
  Role string
}

func main() {
  user := User{Name: "dj", Age: 18}
  employee := Employee{}

  copier.Copy(&employee, &user)
  fmt.Printf("%#v\n", employee)
}

将user对象中的字段赋值到employee的同名字段中。如果目标对象中没有同名的字段,则该字段被忽略。

关于map

对于var定义的map不宜直接赋值,最好使用:=方式初始化,以免出现空指针错误

关于config.yaml

在同时要使用两个yaml时,通过wire依赖注入传入,在provideset中直接接收即可,wire会帮助自动生成代码,eg:
main.go

package main  
  
import (  
"flag"  
"os"  
  
"github.com/go-kratos/beer-shop/app/catalog/service/internal/conf"  
  
"github.com/go-kratos/kratos/v2"  
"github.com/go-kratos/kratos/v2/config"  
"github.com/go-kratos/kratos/v2/config/file"  
"github.com/go-kratos/kratos/v2/log"  
"github.com/go-kratos/kratos/v2/registry"  
"github.com/go-kratos/kratos/v2/transport/grpc"  
"go.opentelemetry.io/otel/exporters/jaeger"  
"go.opentelemetry.io/otel/sdk/resource"  
tracesdk "go.opentelemetry.io/otel/sdk/trace"  
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"  
)  
  
// go build -ldflags "-X main.Version=x.y.z"  
var (  
    // Name is the name of the compiled software.  
    Name = "beer.catalog.service"  
    // Version is the version of the compiled software.  
    Version string  
    // flagconf is the config flag.  
    flagconf string  
)  
  
func init() {  
    flag.StringVar(&flagconf, "conf", "../../configs", "config path, eg: -conf config.yaml")  
}  
  
func newApp(logger log.Logger, gs *grpc.Server, rr registry.Registrar) *kratos.App {  
    return kratos.New(  
        kratos.Name(Name),  
        kratos.Version(Version),  
        kratos.Metadata(map[string]string{}),  
        kratos.Logger(logger),  
        kratos.Server(  
            gs,  
        ),  
        kratos.Registrar(rr),  
    )  
}  
  
func main() {  
    flag.Parse()  
    logger := log.With(
        log.NewStdLogger(os.Stdout),  
        "service.name", Name,  
        "service.version", Version,  
        "ts", log.DefaultTimestamp,  
        "caller", log.DefaultCaller,  
    )  

    c := config.New(  
        config.WithSource(  
        file.NewSource(flagconf),  
    ),  
    )  
    if err := c.Load(); err != nil {  
        panic(err)  
    }  

    var bc conf.Bootstrap  
    if err := c.Scan(&bc); err != nil {  
        panic(err)  
    }  

    var rc conf.Registry  
    if err := c.Scan(&rc); err != nil {  
        panic(err)  
    }  

    exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(bc.Trace.Endpoint)))  
    if err != nil {  
        panic(err)  
    }  
    tp := tracesdk.NewTracerProvider(  
        tracesdk.WithBatcher(exp),  
        tracesdk.WithResource(resource.NewSchemaless(  
            semconv.ServiceNameKey.String(Name),  
        )),  
    )  

    app, cleanup, err := initApp(bc.Server, &rc, bc.Data, logger, tp)  
    if err != nil {  
        panic(err)  
    }  
    defer cleanup()  

    // start and wait for stop signal  
    if err := app.Run(); err != nil {  
        panic(err)  
    }  
}

wire.go

// +build wireinject  
  
// The build tag makes sure the stub is not built in the final build.  
  
package main  
  
import (  
    "github.com/go-kratos/beer-shop/app/catalog/service/internal/biz"  
    "github.com/go-kratos/beer-shop/app/catalog/service/internal/conf"  
    "github.com/go-kratos/beer-shop/app/catalog/service/internal/data"  
    "github.com/go-kratos/beer-shop/app/catalog/service/internal/server"  
    "github.com/go-kratos/beer-shop/app/catalog/service/internal/service"  

    "github.com/go-kratos/kratos/v2"  
    "github.com/go-kratos/kratos/v2/log"  
    "github.com/google/wire"  
    tracesdk "go.opentelemetry.io/otel/sdk/trace"  
)  
  
// initApp init kratos application.  
func initApp(*conf.Server, *conf.Registry, *conf.Data, log.Logger, *tracesdk.TracerProvider) (*kratos.App, func(), error) {  
    panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))  
}

server.go

package server  
  
import (  
    "github.com/go-kratos/beer-shop/app/catalog/service/internal/conf"  
    "github.com/go-kratos/kratos/v2/registry"  
    "github.com/google/wire"  

    consul "github.com/go-kratos/kratos/contrib/registry/consul/v2"  
    consulAPI "github.com/hashicorp/consul/api"  
)  
  
// ProviderSet is server providers.  
var ProviderSet = wire.NewSet(NewGRPCServer, NewRegistrar)  
  
func NewRegistrar(conf *conf.Registry) registry.Registrar {  
    c := consulAPI.DefaultConfig()  
    c.Address = conf.Consul.Address  
    c.Scheme = conf.Consul.Scheme  
    cli, err := consulAPI.NewClient(c)  
    if err != nil {  
        panic(err)  
    }  
    r := consul.New(cli, consul.WithHealthCheck(false))  
    return r  
}