Golang 依赖注入库Wire应用案例

文章目录

  • 简介
  • Github
  • 指南
  • 安装
  • 案例
    • wire.NewSet
    • wire.Build
    • wire.Bind
    • wire.Struct
    • wire.Value
    • wire.InterfaceValue

简介

Go语言的依赖注入库Wire是由Google提供的一个代码生成工具,用于简化和自动化依赖注入过程。Wire主要通过生成代码来处理依赖关系,而不是在运行时动态地解决依赖,这使得它更高效且易于调试。

  • wire.NewSet: NewSet 函数用于创建一个新的依赖集合。你可以将需要被注入的类型和提供这些类型依赖的函数放入到这个集合中。

  • wire.Build: Build 函数用于生成依赖注入代码。你可以将之前创建的依赖集合传递给 Build 函数,然后它将生成相应的代码用于构建依赖。

  • wire.Bind: Bind 函数用于将一个接口类型与其实现类型进行绑定。这样在依赖注入时,当需要注入某个接口类型时,Wire会知道该使用哪个具体的实现类型。

  • wire.Struct: Struct 函数用于将结构体类型与其字段进行绑定。这样在依赖注入时,可以将结构体的字段通过依赖注入的方式进行初始化。

  • wire.Value: Value 函数用于声明一个特定的值作为依赖。在依赖注入时,这个值会被直接使用,而不需要再进行额外的初始化。

  • wire.InterfaceValue: InterfaceValue 函数用于声明一个接口类型的值作为依赖。在依赖注入时,这个值会被用作接口类型的实现。

  • Wire的应用场景:

    • 构建复杂依赖图:Wire特别适用于处理具有复杂依赖关系的应用程序,尤其是当依赖项数量庞大且层次深厚时。

    • 简化初始化逻辑:通过自动生成依赖注入代码,Wire简化了对象的初始化逻辑,使代码更加简洁和易于维护。

    • 提高代码可测试性:通过接口绑定和依赖注入,Wire可以帮助实现松耦合结构,从而提高代码的可测试性。

    • 提升性能:Wire在编译时解析和生成依赖注入代码,因此在运行时不需要额外的依赖解析步骤,这使得它比一些运行时依赖注入框架更高效。

Github

  • https://github.com/google/wire

指南

  • https://github.com/google/wire/blob/main/docs/guide.md

安装

go get github.com/google/wire/cmd/wire
# 安装
go install github.com/google/wire/cmd/wire@latest

案例

wire.NewSet

wire.NewSet 是 Wire 库中用于创建依赖集合的函数。在依赖注入的场景中,你可以使用 wire.NewSet 将多个提供者函数(即构造函数)或现有值组合到一起,形成一个提供依赖项的集合。这对于组织和管理依赖项非常有帮助。

  • 应用场景
    • 分组管理依赖项:你可以将相关的依赖项分组到一个集合中,方便在不同的构建上下文中复用这些依赖项。
    • 模块化设计:通过创建不同的依赖集合,可以更清晰地表达模块之间的依赖关系。
    • 测试:可以创建不同的依赖集合用于测试,以便轻松替换实际依赖项。

wire.Build

wire.Build 是 Wire 库中的核心函数,用于生成依赖注入代码。它通过构建依赖图,根据提供的依赖集合自动生成所需的初始化代码。

  • 应用场景
    • 复杂依赖关系管理:在大型应用程序中,管理复杂的依赖关系是很困难的,使用 wire.Build 可以自动处理这些依赖。
    • 模块化开发:在模块化开发中,每个模块可能有自己的依赖项,通过 wire.Build 可以轻松组合不同模块的依赖。
    • 测试和替换依赖:在测试中,使用 wire.Build 可以方便地替换实际依赖项以进行单元测试。

在这里插入图片描述

  1. 定义依赖项和构造函数:定义 Database, HTTPServer 和 App 结构体,以及它们的构造函数。
  2. 创建依赖集合:使用 wire.NewSet 将构造函数组合成集合 ProviderSet。
  3. 生成依赖注入代码:在 app/wire.go 中,使用 wire.Build 和 ProviderSet 生成依赖注入代码。
  4. 使用生成的代码:在 main.go 中,调用 app.InitApp 函数初始化应用程序。
cd demo
# 初始化
go mod init example.com/demo
# 下载依赖库
go mod tidy
  • app/app.go
package appimport ("github.com/google/wire""example.com/demo/db""example.com/demo/server"
)// App 是我们的应用程序,依赖于 HTTPServer
type App struct {Server *server.HTTPServer
}// NewApp 是 App 的构造函数
func NewApp(server *server.HTTPServer) *App {return &App{Server: server,}
}// ProviderSet 是应用程序模块的依赖集合
var ProviderSet = wire.NewSet(NewApp, db.ProviderSet, server.ProviderSet)
  • app/wire.go
// +build wireinjectpackage appimport ("github.com/google/wire"
)// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {wire.Build(ProviderSet)return &App{}
}
  • app/wire_gen.go
// Code generated by Wire. DO NOT EDIT.//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinjectpackage appimport ("example.com/demo/db""example.com/demo/server"
)// Injectors from wire.go:// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {database := db.NewDatabase()httpServer := server.NewHTTPServer(database)app := NewApp(httpServer)return app
}
  • db/db.go
package dbimport "github.com/google/wire"// Database 是一个简单的数据库连接模拟
type Database struct {DSN string
}// NewDatabase 是 Database 的构造函数
func NewDatabase() *Database {return &Database{DSN: "user:password@/dbname",}
}// ProviderSet 是数据库模块的依赖集合
var ProviderSet = wire.NewSet(NewDatabase)
  • server/server.go
package serverimport ("example.com/demo/db""github.com/google/wire"
)// HTTPServer 是一个简单的 HTTP 服务器
type HTTPServer struct {DB *db.Database
}// NewHTTPServer 是 HTTPServer 的构造函数
func NewHTTPServer(db *db.Database) *HTTPServer {return &HTTPServer{DB: db,}
}// ProviderSet 是服务器模块的依赖集合
var ProviderSet = wire.NewSet(NewHTTPServer)
  • main.go
package mainimport ("fmt""example.com/demo/app"
)func main() {// 调用 app 包中的 InitApp 函数初始化应用myApp := app.InitApp()fmt.Printf("App initialized with server: %+v\n", myApp.Server)
}
  • 生成wire_gen.go
cd demo && wire
# 或
cd demo/app && wire
cd demo
go run .

wire.Bind

wire.Bind 是 Wire 提供的一个功能,用于将接口类型与具体实现类型绑定。这在依赖注入的场景中特别有用,因为它允许你将接口注入到依赖树中,而不是具体实现,从而实现更灵活和可测试的代码结构。

  • 应用场景
    • 接口与实现的解耦:当你的代码依赖于接口而不是具体实现时,可以更容易地更换实现或者进行单元测试。
    • 依赖注入中的多态性:在构建依赖图时,可以选择不同的具体实现绑定到相同的接口上,以实现多态行为。

在这里插入图片描述

  1. 定义接口和实现:在 service 包中定义 Service 接口和 RealService 实现。
  2. 构造函数和 ProviderSet:定义 NewRealService 构造函数和 ProviderSet,并使用 wire.Bind 将 Service 接口绑定到 RealService 实现。
  3. 使用依赖注入:在 app 包中定义 App 结构体及其构造函数 NewApp,并在 ProviderSet 中包含 service.ProviderSet。
  4. 生成 Wire 代码:在 app/wire.go 中使用 wire.Build 和 ProviderSet 生成依赖注入代码。
  5. 初始化应用:在 main.go 中调用 app.InitApp 初始化应用,并调用服务的方法。
  • app/app.go
package appimport ("github.com/google/wire""example.com/demo/service"
)// App 是我们的应用程序,依赖于 Service
type App struct {Service service.Service
}// NewApp 是 App 的构造函数
func NewApp(service service.Service) *App {return &App{Service: service,}
}// ProviderSet 是应用程序模块的依赖集合
var ProviderSet = wire.NewSet(NewApp, service.ProviderSet)
  • app/wire.go
// +build wireinjectpackage appimport ("github.com/google/wire"
)// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {wire.Build(ProviderSet)return &App{}
}
  • app/wire_gen.go
// Code generated by Wire. DO NOT EDIT.//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinjectpackage appimport ("example.com/demo/service"
)// Injectors from wire.go:// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {realService := service.NewRealService()app := NewApp(realService)return app
}
  • service/service.go
package serviceimport ("github.com/google/wire"
)// Service 是一个接口,定义了服务的行为
type Service interface {Serve() string
}// RealService 是 Service 接口的具体实现
type RealService struct{}// Serve 是 RealService 的 Serve 方法实现
func (s *RealService) Serve() string {return "Real service serving"
}// NewRealService 是 RealService 的构造函数
func NewRealService() *RealService {return &RealService{}
}// ProviderSet 是服务模块的依赖集合
var ProviderSet = wire.NewSet(NewRealService,wire.Bind(new(Service), new(*RealService)),
)
  • main.go
package mainimport ("fmt""example.com/demo/app"
)func main() {// 调用 app 包中的 InitApp 函数初始化应用myApp := app.InitApp()fmt.Println(myApp.Service.Serve())
}

wire.Struct

wire.Struct 是 Wire 提供的一个功能,用于简化结构体的构造。当一个结构体有多个字段需要注入时,wire.Struct 可以自动生成构造函数,注入所有字段。它特别适用于需要依赖注入的复杂结构体。

  • 应用场景
    • 简化构造函数:当一个结构体有很多字段时,手动编写构造函数可能会很繁琐,使用 wire.Struct 可以自动生成构造函数。
    • 减少样板代码:在大型项目中,减少手动编写的构造函数代码,提高开发效率。
    • 保证依赖注入的正确性:通过自动生成构造函数,减少人为错误。

在这里插入图片描述

  1. 定义结构体:在 app 包中定义 App 结构体,它依赖于 HTTPServer 和 Database。
  2. 使用 wire.Struct:在 ProviderSet 中使用 wire.Struct(new(App), “*”),表示将自动生成 App 的构造函数并注入所有字段。
  3. 生成依赖注入代码:在 app/wire.go 中使用 wire.Build 和 ProviderSet 生成依赖注入代码。
  4. 初始化应用:在 main.go 中调用 app.InitApp 函数初始化应用。
  • app/app.go
package appimport ("github.com/google/wire""example.com/demo/db""example.com/demo/server"
)// App 是我们的应用程序,依赖于 HTTPServer 和 Database
type App struct {Server *server.HTTPServerDb     *db.Database
}// ProviderSet 是应用程序模块的依赖集合
var ProviderSet = wire.NewSet(wire.Struct(new(App), "*"), db.ProviderSet, server.ProviderSet)
  • app/wire.go
// +build wireinjectpackage appimport ("github.com/google/wire"
)// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {wire.Build(ProviderSet)return &App{}
}
  • app/wire_gen.go
// Code generated by Wire. DO NOT EDIT.//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinjectpackage appimport ("example.com/demo/db""example.com/demo/server"
)// Injectors from wire.go:// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {database := db.NewDatabase()httpServer := server.NewHTTPServer(database)app := &App{Server: httpServer,Db:     database,}return app
}
  • db/db.go
package dbimport "github.com/google/wire"// Database 是一个简单的数据库连接模拟
type Database struct {DSN string
}// NewDatabase 是 Database 的构造函数
func NewDatabase() *Database {return &Database{DSN: "user:password@/dbname",}
}// ProviderSet 是数据库模块的依赖集合
var ProviderSet = wire.NewSet(NewDatabase)
  • server/server.go
package serverimport ("example.com/demo/db""github.com/google/wire"
)// HTTPServer 是一个简单的 HTTP 服务器
type HTTPServer struct {DB *db.Database
}// NewHTTPServer 是 HTTPServer 的构造函数
func NewHTTPServer(db *db.Database) *HTTPServer {return &HTTPServer{DB: db,}
}// ProviderSet 是服务器模块的依赖集合
var ProviderSet = wire.NewSet(NewHTTPServer)
  • main.go
package mainimport ("fmt""example.com/demo/app"
)func main() {// 调用 app 包中的 InitApp 函数初始化应用myApp := app.InitApp()fmt.Printf("App initialized with server: %+v\n", myApp.Server)
}

wire.Value

wire.Value 是 Wire 提供的一个功能,用于注入一个特定的值。这在配置项或常量注入等场景中特别有用,能够为依赖注入过程提供静态的值。

  • 应用场景
    • 配置注入:将配置项(如数据库连接字符串、API 密钥等)注入到依赖树中。
    • 静态值注入:对于某些不会改变的常量值,使用 wire.Value 注入这些值。
    • 默认值注入:为某些依赖项提供默认值。

在这里插入图片描述

  1. 定义配置结构体:在 config 包中定义 Config 结构体和 NewConfig 构造函数。
  2. 使用 wire.Value:在 config.ProviderSet 中使用 wire.Value(Config{DSN: “user:password@/dbname”}) 注入静态配置值。
  3. 定义数据库结构体:在 db 包中定义 Database 结构体和 NewDatabase 构造函数。
  4. 构建依赖树:在 app 包中定义 App 结构体及其构造函数 NewApp,并在 ProviderSet 中包含 db.ProviderSet 和 config.ProviderSet。
  5. 生成依赖注入代码:在 app/wire.go 中使用 wire.Build 和 ProviderSet 生成依赖注入代码。
  6. 初始化应用:在 main.go 中调用 app.InitApp 函数初始化应用。
  • app/app.go
package appimport ("github.com/google/wire""example.com/demo/db"
)// App 是我们的应用程序,依赖于 Database
type App struct {Database *db.Database
}// NewApp 是 App 的构造函数
func NewApp(database *db.Database) *App {return &App{Database: database,}
}// ProviderSet 是应用程序模块的依赖集合
var ProviderSet = wire.NewSet(NewApp, db.ProviderSet)
  • app/wire.go
// +build wireinjectpackage appimport ("github.com/google/wire""example.com/demo/config"
)// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {wire.Build(ProviderSet, config.ProviderSet)return &App{}
}
  • app/wire_gen.go
// Code generated by Wire. DO NOT EDIT.//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinjectpackage appimport ("example.com/demo/config""example.com/demo/db"
)// Injectors from wire.go:// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {config := _wireConfigValuedatabase := db.NewDatabase(config)app := NewApp(database)return app
}var (_wireConfigValue = config.Config{DSN: "user:password@/dbname"}
)
  • config/config.go
package configimport "github.com/google/wire"// Config 是一个简单的配置结构体
type Config struct {DSN string
}// NewConfig 是 Config 的构造函数
func NewConfig(dsn string) *Config {return &Config{DSN: dsn,}
}// ProviderSet 是配置模块的依赖集合
var ProviderSet = wire.NewSet(wire.Value(Config{DSN: "user:password@/dbname"}),
)
  • db/db.go
package dbimport ("example.com/demo/config""github.com/google/wire"
)// Database 是一个简单的数据库连接模拟
type Database struct {DSN string
}// NewDatabase 是 Database 的构造函数
func NewDatabase(config config.Config) *Database {return &Database{DSN: config.DSN,}
}// ProviderSet 是数据库模块的依赖集合
var ProviderSet = wire.NewSet(NewDatabase)
  • main.go
package mainimport ("fmt""example.com/demo/app"
)func main() {// 调用 app 包中的 InitApp 函数初始化应用myApp := app.InitApp()fmt.Printf("App initialized with database DSN: %+v\n", myApp.Database.DSN)
}

wire.InterfaceValue

wire.InterfaceValue 是 Wire 提供的一个功能,用于将一个特定的实现绑定到一个接口。这在依赖注入中非常有用,特别是在你有多个实现并且希望在运行时或编译时决定使用哪个实现的情况下。

  • 应用场景
    • 接口实现的动态选择:当你的代码依赖于接口而不是具体实现时,可以使用 wire.InterfaceValue 动态选择不同的实现。
    • 配置驱动的实现选择:根据配置或环境变量选择不同的实现。
    • 测试替身的注入:在测试中,可以用 wire.InterfaceValue 注入模拟或替身实现。

在这里插入图片描述

  1. 定义接口和实现:在 service 包中定义 Service 接口和 RealService, MockService 实现。
  2. 配置选择实现:在 config 包中定义 SelectedService 函数,用于选择具体的服务实现。
  3. 使用 wire.InterfaceValue:在 app/wire.go 中使用 wire.InterfaceValue 将 config.SelectedService() 的返回值绑定到 Service 接口。
  4. 构建依赖树:在 app 包中定义 App 结构体及其构造函数 NewApp,并在 ProviderSet 中包含 service.ProviderSet。
  5. 生成依赖注入代码:在 app/wire.go 中使用 wire.Build 和 ProviderSet 生成依赖注入代码。
  6. 初始化应用:在 main.go 中调用 app.InitApp 函数初始化应用,并调用服务的方法。
  • app/app.go
package appimport ("github.com/google/wire""example.com/demo/service"
)// App 是我们的应用程序,依赖于 Service
type App struct {Service service.Service
}// NewApp 是 App 的构造函数
func NewApp(service service.Service) *App {return &App{Service: service,}
}// ProviderSet 是应用程序模块的依赖集合
var ProviderSet = wire.NewSet(NewApp, service.ProviderSet)
  • app/wire.go
// +build wireinjectpackage appimport ("github.com/google/wire""example.com/demo/config""example.com/demo/service"
)// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {wire.Build(ProviderSet,wire.InterfaceValue(new(service.Service), config.SelectedService()),)return &App{}
}
  • app/wire_gen.go
// Code generated by Wire. DO NOT EDIT.//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinjectpackage appimport ("example.com/demo/config"
)// Injectors from wire.go:// InitApp 使用 Wire 生成依赖注入代码
func InitApp() *App {service := _wireServiceValueapp := NewApp(service)return app
}var (_wireServiceValue = config.SelectedService()
)
  • config/config.go
package configimport "example.com/demo/service"// SelectedService 返回要使用的服务实现
func SelectedService() service.Service {// 根据需要选择实际的服务实现,这里可以是基于配置或环境变量的逻辑return &service.RealService{}
}
  • db/db.go
package dbimport ("example.com/demo/config""github.com/google/wire"
)// Database 是一个简单的数据库连接模拟
type Database struct {DSN string
}// NewDatabase 是 Database 的构造函数
func NewDatabase(config config.Config) *Database {return &Database{DSN: config.DSN,}
}// ProviderSet 是数据库模块的依赖集合
var ProviderSet = wire.NewSet(NewDatabase)
  • service/service.go
package serviceimport "github.com/google/wire"// Service 是一个接口,定义了服务的行为
type Service interface {Serve() string
}// RealService 是 Service 接口的一个具体实现
type RealService struct{}func (s *RealService) Serve() string {return "Real service serving"
}// MockService 是 Service 接口的另一个具体实现
type MockService struct{}func (s *MockService) Serve() string {return "Mock service serving"
}// ProviderSet 是服务模块的依赖集合
var ProviderSet = wire.NewSet()
  • main.go
package mainimport ("fmt""example.com/demo/app"
)func main() {// 调用 app 包中的 InitApp 函数初始化应用myApp := app.InitApp()fmt.Println(myApp.Service.Serve())
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/347744.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

炒币千万条,安全第一条,The First提示您:警惕账户风险,守护资产安全

随着区块链技术的飞速发展和数字资产的普及,越来越多的人选择进入加密货币的世界进行投资。与此同时,黑客和诈骗分子的手段也在不断升级,给投资者的账户安全带来了严峻挑战。 近期,交易所安全事件频发,有黑客和诈骗分子…

Hadoop3:MapReduce源码解读之Map阶段的Job任务提交流程(1)

3、Job工作机制源码解读 用之前wordcount案例进行源码阅读,debug断点打在Job任务提交时 提交任务前,建立客户单连接 如下图,可以看出,只有两个客户端提供者,一个是YarnClient,一个是LocalClient。 显然&a…

DevExpress WPF中文教程:Grid - 如何向项目添加GridControl并绑定到数据

DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

知识付费平台功能模块详解

知识付费平台作为一种新兴的在线教育模式,以其用户需求导向的设计理念和便捷高效的学习方式,受到了广泛欢迎。这类平台汇集了职业技能、生活兴趣和人文社科等多领域的专业知识,并通过视频播放、在线问答、作业批改等工具和服务,助…

零售商为什么分析用户数据?盘点六大零售业用户分析常用模型

在当今这个数据驱动的时代,零售行业正面临着前所未有的机遇与挑战。随着消费者行为的日益多样化和市场竞争的不断加剧,零售商们迫切需要有效的方法来洞察市场动态,优化运营策略,并最终实现业务的持续增长。用户数据分析&#xff0…

DOS 命令

Dos: Disk Operating System 磁盘操作系统, 简单说一下 windows 的目录结构。 ..\ 到上一级目录 常用的dos 命令: 查看当前目录是有什么内容 dir dir d:\abc2\test200切换到其他盘下:盘符号 cd : change directory 案例演示:切换…

GEO ISP图像调试-PFC(蓝紫边校正)

目录 1、简单介绍 2、调试策略 3、输出结果 1、简单介绍 GEO中中调整图像蓝紫边可分为两步,第一步:调整蓝紫边检测区域,第二步:设置去蓝紫边强度。 2、调试策略 图1 该图像蓝紫边较严重 主要原因是由于蓝紫边检测不准导致的&…

使用GPT-soVITS再4060下2小时训练声音模型以及处理断句带来的声音模糊问题

B站UP主视频 感谢UP主“白菜工厂1145号员工”的“熟肉”,我这篇笔记就不展示整一个训练和推理流程,重点写的4060该注意的一些事项。如何解决断句模糊的问题,在本篇笔记的最末尾。 相关连接: 原项目github UP主的说明文档 1、训…

【全开源】JAVA短剧国际版源码支持H5+Android+IOS

🌍探索国际版短剧源码:打造你的全球影视平台 🚀一、引言:短剧时代的崛起 在数字化快速发展的今天,短剧作为一种新兴的影视形式,凭借其紧凑的剧情和高效的观看体验,逐渐在全球范围内崭露头角。…

[ue5]建模场景学习笔记(5)——必修内容可交互的地形,交互沙(2)

1需求分析: 继续制作可交互沙子内容,前面我们已经让角色在指定区域留下痕迹,那么能否让区域移动起来,这样才能逐步满足角色走到哪里都能产生交互痕迹,满足更大的地图。 2.操作实现: 1.首先建立角色能产生…

5.4 安全策略和控制 方法实现探讨

安全策略概述: 定义 安全策略是一组规则和措施,旨在保护组织的信息和资产免受潜在的威胁和攻击。它的制定和实施需要考虑组织的特定需求和风险,并采取适当的措施来减少潜在的安全漏洞。安全策略的定义包括以下几个方面: 1. 目标和范围&…

源代码加密的十个关键点

源代码加密是一种安全措施,其目的是为了保护软件的源代码不被未授权的个人或实体访问或泄露。源代码是软件应用程序的基础,它包含了程序的逻辑结构、核心算法以及设计理念。由于源代码承载了软件的核心知识和创新,因此它具有极高的商业价值和…

【工程实践】gradio调用模型与展示

前言 模型在云端部署好之后,衍生出Flask、Fastapi的接口,可以借助gradio调用接口展示在前端。 1.gradio代码 import gradio as gr import requests import json #调用部署的云服务接口 def greet(question):prefix_url http://0.0.0.0/get_classificat…

matlab BP神经网络

clear clc % 准备数据 inputs rand(10, 100); % 100组输入,每组10个特征 outputs rand(1, 100); % 100组输出,每组1个输出值 % 将数据分成训练集和测试集 trainRatio 0.8; valRatio 0.1; testRatio 0.1; [trainInd, valInd, testInd] divid…

如何下载iSlide软件及详细安装步骤

iSlide插件是一款能够支持PPT和WPS的ppt插件,旨在让每一个人都能够轻松制作出精美的ppt,能够在职场收到更多的关注,而该软件的口号正是「让 PPT 设计简单起来」,该插件是由原来NT插件升级改良过来的,在功能上面进行了全…

react快速开始(四)-之Vite 还是 (Create React App) CRA? 用Vite创建项目

文章目录 react快速开始(四)-之Vite 还是 (Create React App) CRA? 用Vite创建项目背景Vite 和 (Create React App) CRAVite?Vite 是否支持 TypeScript? 用Vite创建react项目参考 react快速开始(四)-之Vite 还是 (Create React App) CRA? 用Vite创建项…

C# WinForm —— 33 ContextMenuStrip介绍

1. 简介 右键某个控件/窗体时,弹出来的菜单,比如VS中右键窗体,弹出来的这个菜单: 和MenuStrip类似,ContextMenuStrip主菜单下面可以有子菜单,子菜单下面可以有下一级子菜单 2. 属性 和MenuStrip一样 …

Java的一些补充性介绍

目录 什么是JDK,JRE 快速入门 学习路线: 如何快速掌握技术或知识点: IDEA 常用快捷键 IDEA创建项目、模块、包、类 模板/自定义模板 包 包的命名:​编辑 常用的包 如引入包 断点调试(debug)​编辑 多线程:…

i.MX8MP平台开发分享(RDC软件配置篇)

Uboot中已经将RDC的配置写入到了OCRAM中,NXP在ATF中预设了SIP服务,SIP服务下有厂商自定义的smc命令ID。例如下面的DDR、GPC、SRC和HAB的smc回调函数。 在SRC中断处理函数中,对于SRC_M4_START指令,先读取OCRAM中的配置,…

Hadoop3:MapReduce源码解读之Map阶段的数据输入过程整体概览(0)

一、MapReduce中数据流向 二、MapTask并行度 1、原理概览 数据块:Block是HDFS物理上把数据分成一块一块。数据块是HDFS存储数据单位。 数据切片:数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。数据切片是MapRed…