怎么建设58同城网站dw怎么做网站首页

web/2025/9/29 5:06:00/文章来源:
怎么建设58同城网站,dw怎么做网站首页,wordpress中英,免费手机端网站模板我为什么要直接写番外呢#xff1f;其原因很简单。项目中会使用#xff0c;其实在这里大家就可以写一些项目来了。 依赖注入的工具本质思想其实都大差不差。无非控制反转和依赖注入。 文章目录 控制反转为什么需要依赖注入工具 wire的概念提供者#xff08;provider#x…我为什么要直接写番外呢其原因很简单。项目中会使用其实在这里大家就可以写一些项目来了。 依赖注入的工具本质思想其实都大差不差。无非控制反转和依赖注入。 文章目录 控制反转为什么需要依赖注入工具 wire的概念提供者providerInjector注入器注意 wire的使用特性绑定接口结构体提供者指针结构体传入的中注入MyFoo字段 重要 绑定值接口值 使用结构的字段作为提供者Cleanup函数 控制反转 控制反转Inversion of Control缩写为IoC是面向对象编程中的一种设计原则可以用来减低计算机代码之间的耦合度。 其中最常见的方式叫做依赖注入Dependency Injection简称DI 还有一种方式通过依赖查找。这个我在我之前的Spring的文章中有写感兴趣的朋友可以移步。 依赖注入是生成灵活和松散耦合代码的标准技术通过明确地向组件提供它们所需要的所有依赖关系。 在 Go 中通常采用将依赖项作为参数传递给构造函数的形式 构造函数NewBookRepo在创建BookRepo时需要从外部将依赖项db作为参数传入我们在NewBookRepo中无需关注db的创建逻辑实现了代码解耦。 // NewBookRepo 创建BookRepo的构造函数 func NewBookRepo(db *gorm.DB) *BookRepo {return BookRepo{db: db} }对于控制反转来说如果在NewBookPepo 函数中自行创建相关依赖使得代码的耦合度比较高并且难以维护和调试。 为了解决这个问题大佬们就开始想办法在还华中尽可能的使用控制反转和依赖注入将程序解耦合开从而写出灵活并易于测试的程序。 为什么需要依赖注入工具 在小型应用程序中我们可以自行创建依赖并手动注入。但是在一个大型应用程序中手动去实现所有依赖的创建和注入就会比较繁琐。 为了方便管理业务和技术分层会在实际中划分住不同的代码层。其中MVC就是一个非常常见的业务思想。 例如 HTTP服务中 这中模型是最为常见的的模型。 服务需要有一个配置指定工作模式、连接的数据库和监听端口等信息。conf 目录: conf/conf.go // conf/conf.go// NewDefaultConfig 返回默认配置不需要依赖 func NewDefaultConfig() *Config {...}这里定义了一个默认配置当然后续可以支持从配置文件或环境变量读取配置信息 在程序的data层需要定义一个连接数据库的函数它依赖上面定义的Config并返回一个*gorm.DB这里使用gorm连接数据库 目录data/data.go // data/data.go// NewDB 返回数据库连接对象 func NewDB(cfg *conf.Config) (*gorm.DB, error) {...}同时定义一个BookRepo它有一些数据操作相关的方法。它的构造函数NewBookRepo依赖*gorm.DB并返回一个*BookRepo。 目录:data/data.go // data/data.gotype BookRepo struct {db *gorm.DB }func NewBookRepo(db *gorm.DB) *BookRepo {...}Service层位于data层和Server层的中间它负责实现对外服务。其中构造函数 NewBookService 依赖Config和BookRepo 目录service/service.go // service/service.gotype BookService struct {config *conf.Configrepo *data.BookRepo }func NewBookService(cfg *conf.Config, repo *data.BookRepo) *BookService {...}server层又有一个NewServer构造函数它依赖外部传入Config和BookService 目录server/server.go // server/server.gotype Server struct {config *conf.Configservice *service.BookService }func NewServer(cfg *conf.Config, srv *service.BookService) *Server {...}在main.go文件中又依赖Server创建一个app 目录:main.go // main.gotype Server interface {Run() }type App struct {server Server }func newApp(server Server) *App {...}由于在程序中定义了大量需要依赖注入的构造函数程序的main函数中会出现以下情形。 目录main.go // main.gofunc main() {cfg : conf.NewDefaultConfig()db, _ : data.NewDB(cfg)repo : data.NewBookRepo(db)bookSrv : service.NewBookService(cfg, repo)server : server.NewServer(cfg, bookSrv)app : newApp(server)app.Run() }所有依赖的创建和顺序都需要手动维护。 故我们就需要一个工具来解决这个问题。 wire的概念 Go社区中有很多依赖注入框架。比如Uber的dig和Facebook的inject都使用反射来做运行时依赖注入。 Wire 是一个的 Google 开源的依赖注入工具通过自动生成代码的方式在编译期完成依赖注入。 wire中有两个核心概念提供者provider和注入器injector 提供者provider 提供者函数可以分组为提供者函数集provider set。使用wire.NewSet 函数可以将多个提供者函数添加到一个集合中。如果经常同时使用多个提供者函数这非常有用。 package demoimport (// ...github.com/google/wire )// ...var ProviderSet wire.NewSet(NewX, NewY, NewZ)而这个集合也可以作为提供者函数。 package demoimport (// ...example.com/some/other/pkg ) var MegaSet wire.NewSet(ProviderSet, pkg.OtherSet)而提供者函数可以实现这几种方式。 可以产生值的普通函数 type X struct {Value int }// NewX 返回一个X对象 func NewX() X {return X{Value: 7} }可以使用参数指定依赖项 type Y struct {Value int }// NewY 返回一个Y对象需要传入一个X对象作为依赖。 func NewY(x X) Y {return Y{Value: x.Value1} }可以返回错误的 type Z struct {Value int }// NewZ 返回一个Z对象当传入依赖的value为0时会返回错误。 func NewZ(ctx context.Context, y Y) (Z, error) {if y.Value 0 {return Z{}, errors.New(cannot provide z when value is zero)}return Z{Value: y.Value 2}, nil }Injector注入器 应用程序中是用一个注入器来连接提供者注入器就是一个按照依赖顺序调用提供者。 使用 wire时你只需要编写注入器的函数签名然后 wire会生成对应的函数体 要声明一个注入器函数只需要在函数体中调用wire.Build 这个函数的返回值也无关紧要只要它们的类型正确即可。这些值在生成的代码中将被忽略。 假设上面的提供者函数是在一个名为 wire_demo/demo 的包中定义的下面将声明一个注入器来得到一个Z函数 package mainimport (contextgithub.com/google/wirewire_demo/demo ) func initZ(ctx context.Context) (demo.Z, error) {wire.Build(demo.ProviderSet)return demo.Z{}, nil }wire.Build的参数和wire.NewSet一样都是提供者集合。这些就在该注入器的代码生成期间使用的提供者集。 将上面的代码保存到wire.go中文件最上面的//go:build wireinject 是必须的Go 1.18之前的版本使用// build wireinject它确保wire.go不会参与最终的项目编译。 注意 在实际运用中我要根据实际业务层封装不同的wrie的go类这样方便管理。在哪里调用什么清晰明了 wire的使用 安装wire命令行工具。 命令行 go install github.com/google/wire/cmd/wirelatest 在wire.go同级目录下执行以下命令: wire wire会在同级目录下wire_gen.go文件中生成注入器的具体实现。 生成代码-----》 // Code generated by Wire. DO NOT EDIT.//go:generate go run github.com/google/wire/cmd/wire //go:build !wireinject // build !wireinjectpackage mainimport (contextwire_demo/demo )// Injectors from wire.go:func initZ(ctx context.Context) (demo.Z, error) {x : demo.NewX()y : demo.NewY(x)z, err : demo.NewZ(ctx, y)if err ! nil {return demo.Z{}, err}return z, nil }从生成的内容可以看出wire生成的内容非常接近开发人员自己编写的内容。 此外运行时对wire的依赖性很小所有编写的代码都只是普通的Go代码可以在没有wire的情况下使用。 特性 绑定接口 依赖项注入通常用于绑定接口的具体实现。 wire通过类型标识将输入与输出匹配因此倾向于创建一个返回接口类型的提供者。这不是习惯写法因为Go的最佳实践是返回具体类型。 你可以在提供者集中声明接口绑定 type Fooer interface {Foo() string }type MyFooer stringfunc (b *MyFooer) Foo() string {return string(*b) }func provideMyFooer() *MyFooer {b : new(MyFooer)*b Hello, World!return b }type Bar stringfunc provideBar(f Fooer) string {// f will be a *MyFooer.return f.Foo() }var Set wire.NewSet(provideMyFooer,wire.Bind(new(Fooer), new(*MyFooer)),provideBar, )wire.Bind的第一个参数是指向所需接口类型值的指针第二个参数是指向实现该接口的类型值的指针。任何包含接口绑定的集合还必须具有提供具体类型的提供者。 结构体提供者 可以使用提供的类型构造结构体。 使用wire.Struct函数构造一个结构体类型并告诉注入器应该注入哪个字段。 注入器将使用字段类型的提供程序填充每个字段。 type Foo int type Bar intfunc ProvideFoo() Foo {/* ... */}func ProvideBar() Bar {/* ... */}type FooBar struct {MyFoo FooMyBar Bar }var Set wire.NewSet(ProvideFoo,ProvideBar,wire.Struct(new(FooBar), MyFoo, MyBar), )这个wire会生成一个类似于 func injectFooBar() FooBar {foo : ProvideFoo()bar : ProvideBar()fooBar : FooBar{MyFoo: foo,MyBar: bar,}return fooBar }wire.Struct的第一个参数是指向所需结构体类型的指针随后的参数是要注入的字段的名称。可以使用一个特殊的字符串“*”作为快捷方式告诉注入器注入结构体的所有字段。 指针结构体传入的中 对于生成的结构体类型Swire.struct同时提供S和*S 注入MyFoo字段 var Set wire.NewSet(ProvideFoo,wire.Struct(new(FooBar), MyFoo), )1.生成的类似于 func injectFooBar() FooBar {foo : ProvideFoo()fooBar : FooBar{MyFoo: foo,}return fooBar }2.生成的类似于 func injectFooBar() *FooBar {foo : ProvideFoo()fooBar : FooBar{MyFoo: foo,}return fooBar }重要 有时防止结构体的某些字段被注入器填充很有必要尤其是在将*传递给wire.Struct的时候。你可以用wire:-标记字段使wire忽略这些字段。 type Foo struct {mu sync.Mutex wire:-Bar Bar }使用wire.Struct(new(Foo), *)提供Foo类型时wire将自动省略mu字段。 此外在wire.Struct(new(Foo), mu)中显式指定被忽略的字段也会报错。 绑定值 有时将基本值通常为nil绑定到类型是有用的。 你可以向提供程序集添加一个值表达式而不是让注入器依赖于一次性提供者函数。 type Foo struct {X int }func injectFoo() Foo {wire.Build(wire.Value(Foo{X: 42}))return Foo{} }生成的注入器 func injectFoo() Foo {foo : _wireFooValuereturn foo }var (_wireFooValue Foo{X: 42} )值得注意的是表达式将被复制到注入器的包中。 对变量的引用将在注入器包的初始化过程中进行计算。如果表达式调用任何函数或从任何通道接收任何函数wire 将会报错。 接口值 对于接口值使用 InterfaceValue。 func injectReader() io.Reader {wire.Build(wire.InterfaceValue(new(io.Reader), os.Stdin))return nil }使用结构的字段作为提供者 用户想要的提供程序是结构的某些字段如果发现自己在下面的示例中编写了一个类似getS的提供者可以尝试将结构字段作为所提供的类型 type Foo struct {S stringN intF float64 }func getS(foo Foo) string {// Bad! Use wire.FieldsOf instead.return foo.S }func provideFoo() Foo {return Foo{ S: Hello, World!, N: 1, F: 3.14 } }func injectedMessage() string {wire.Build(provideFoo,getS,)return }可以使用wire.FieldsOf直接使用结构体的字段而无需编写一个类似getS的函数 func injectedMessage() string {wire.Build(provideFoo,wire.FieldsOf(new(Foo), S),)return }生成为 func injectedMessage() string {foo : provideFoo()string2 : foo.Sreturn string2 }可以根据需要将任意多的字段名称添加到wire.FieldsOf中 Cleanup函数 如果提供程序创建了一个需要清理的值例如关闭文件、关闭数据库连接等那么它可以返回一个闭包来清理资源。 注入器将使用它向调用方返回聚合清理函数或者在注入器实现中稍后调用的提供程序返回错误时清理资源。 func provideFile(log Logger, path Path) (*os.File, func(), error) {f, err : os.Open(string(path))if err ! nil {return nil, nil, err}cleanup : func() {if err : f.Close(); err ! nil {log.Log(err)}}return f, cleanup, nil }注意 cleanup函数的签名必须是func()并且保证在提供者的任何输入的cleanup函数之前调用。 总而言之这个番外还是蛮简单的。

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

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

相关文章

网络创建公司网站苏州网站建设培训

在Python中,字符串遍历是一个常见的操作,它允许我们逐个访问字符串中的每个字符。下面将详细讲解Python字符串遍历的几种方式,并结合示例代码进行说明。 1. 使用for…in循环遍历字符串 for…in循环是Python中最常用的遍历字符串的方式。这种…

网站的软文 怎么做推广方案西地那非片有依赖性吗

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

网站首页布局设计互联网行业前景分析

10个人围成一圈,从1到10编号,从1开始数,数到3或3的倍数的位置,则该位置的人出局,求最后剩下哪一个号? 数组解法: 数组存放数组:a[10]存在1到10编号人 数组遍历到尾部又从头遍历&…

asp+sql server典型网站建设案例公司网站上传图片

在地理信息系统(GIS)的应用中,我们经常需要对地图上的面要素进行精确的分割或裁切。 ArcGIS Pro作为一款强大的GIS软件,提供了多种工具来满足这一需求。 本文将详细介绍如何在ArcGIS Pro中使用线要素对面要素进行分割和裁切&…

网站制作有名 乐云践新专家wordpress分类含有中文

转义字符的应用 案列1:很多转义字符的作用是专门针对于打印机的,比如\b1、使用“Y”和“-”;2、打印Y,光标在Y后3、退格,这时光标落在Y字符处,由于是打印机,Y还是留了下来,就打出“”。案例2&am…

服装网站建设策划案苏州网站建设一站通

深度学习中最常用的数据是张量,对张量进行操作是进行深度学习的基础。以下是对张量进行的一些操作: 首先我们需要先导入相关的张量库torch。 元素构造(初始化) 使用arange创造一个行向量,也就是0轴(0维&a…

工业设计代做网站h5响应式网站技术

非空G个数G的大小n的奇偶性答案>4\\D3\奇数D3至少一个大小>2\D3均为1偶数D-12大小均>2\D2至少一个大小>2奇数D2一个大小1,一个大小>1偶数D-12均为1奇数D-12均为1偶数

查询域名是否做过网站云上铺会员管理系统

参展企业介绍 尚鼎环境科技(江苏)有限公司设立于2010年,公司坐落于江南平原南端素有『苏北门户』之称的古城扬州,办公室位在江苏省扬州市邗江区高新技术创业服务中心。 尚鼎环境科技长年致力于食品精炼/环境工程领域全程技术服务,工程实绩遍…

网站查询工信部海宏集团网站建设方案

文章目录 前言模块添加方法双特征提取例子`GhostNet+ShuffleNet` 双主干结构图代码`Swin+ShuffleNet` 双主干结构图代码参数量与计算量1. 什么是YOLO-Magic框架?2. 如何加入这个框架?3. 加入后如何使用框架?4. GitHub组织是什么?

长春哪里有做网站的邢台市教育局官网

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一: 四.修复建议: 五. 搜索语法: 六.免责声明 一.概述 D-Tale数据可视化插件是后端框架Flask与前端框架React组合产生的一款开源的数据可视化分析插件。 目前支持DataFrame、Series、Mu…

广州品牌设计网站建设首页通知书

最近应该很多和我一样的双非鼠鼠在秋招等面试,而且处于海投阶段,为了不忘记投了哪些公司,可以用这样一个表格来记录: 其中有些字段,比如状态、投递时间、查看进度的网址其实可以不手动输入,所以搞个插件来…

网站建设的缺陷对比的网站建设

在《Umi 小白纪实(一)》中有提到过简单的路由配置和使用,但这只是冰山一角借用一句广告词,Umi 路由的能量,超乎你的想象一、基本用法Umi 的路由根结点是全局 layout src/layouts/index.js路由会将相应的页面组件映射到上面的 props.children…

宁夏城乡建设厅网站网站建设公司 - 百度

1.strlen的使用和模拟实现 • 字符串以 \0 作为结束标志,strlen函数返回的是在字符串中 \0 前⾯出现的字符个数(不包 含 \0 )。 • 参数指向的字符串必须要以 \0 结束。 • 注意函数的返回值为size_t,是⽆符号的( 易错 &#xff…

微网站开发入门浙江建站管理系统价格

前篇文章解决了关于函数指针的不同类成员函数传递的问题。不知道细心的朋友看见我上篇文章后,是否发现参数必须被限制为特定的参数。 原来改进的代码如下: class CCallFuctionList { public:CCallFuctionList(); virtual ~CCallFuctionL…

杭州市网站制作英雄联盟网站源码

目录 一.static 简介二.static 修饰变量 1.static 局部静态变量2.static 全局静态变量 三.static 修饰函数四.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 一.static 简介 在 C 语言中,static 关键字不仅可以用来修饰变量&#xff…

现在网站一般做多大的遵义湘江投资建设有限责任公司门户网站

文章目录 Springboot整合Flowable Modeler1 项目准备1.1 新建一个Springboot项目1.2 项目的pom文件1.3 Flowable Modeler UI下载2 后端代码2.1 复制代码2.2 代码修改2.3 新增代码3 启动项目Springboot整合Flowable Modeler 1 项目准备 1.1 新建一个Springboot项目 ​ Spring…

uc官网网站开发者中心网站失败的原因

1082 射击比赛 (20 分) 本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军;谁差得最远,谁就是菜鸟。本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟。我们假设靶心在原点(0,0)。…

wordpress 还是织梦seo整站如何优化

TK矩阵的应用场景 TK矩阵系统适用于多个场景,尤其是在以下几个方面有显著优势: 批量账号管理与内容发布:对于需要管理多个TikTok账号的内容创作者或营销人员,TK矩阵提供了高效的账号管理工具,支持批量发布视频、评论、…

网站建设推进表营销型 手机网站制作

55. 跳跃游戏 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例 1 …