偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Wire:Go語(yǔ)言依賴(lài)注入的利器

開(kāi)發(fā) 前端
Wire 是一個(gè)強(qiáng)大而簡(jiǎn)單的依賴(lài)注入框架,它可以幫助我們更輕松地管理和注入依賴(lài)關(guān)系,從而提高代碼的質(zhì)量、可維護(hù)性和可測(cè)試性。

一、介紹

依賴(lài)注入可以幫助我們更好地管理代碼之間的依賴(lài)關(guān)系,從而提高代碼的可維護(hù)性、可測(cè)試性和可擴(kuò)展性。

但是,手動(dòng)管理依賴(lài)關(guān)系往往會(huì)導(dǎo)致代碼復(fù)雜和冗余,為了解決這個(gè)問(wèn)題,本文我們要介紹的是一款名為 Wire[1] 的依賴(lài)注入框。

Wire 是一個(gè)靜態(tài)類(lèi)型檢查的依賴(lài)注入框架,能夠在編譯時(shí)檢測(cè)到依賴(lài)關(guān)系中的錯(cuò)誤,并提供相應(yīng)的錯(cuò)誤提示。這有助于減少錯(cuò)誤并提高代碼的質(zhì)量和健壯性

二、提供者(Providers)和注入者(Injectors)

使用 Wire 進(jìn)行依賴(lài)注入時(shí),通??梢詫⑴c注入的組件分為兩類(lèi):提供者(Providers)和注入者(Injectors)。

  1. 提供者(Providers):提供者是負(fù)責(zé)創(chuàng)建和提供依賴(lài)項(xiàng)實(shí)例的函數(shù)或方法。它們通常是構(gòu)造函數(shù)或工廠(chǎng)函數(shù),用于創(chuàng)建特定類(lèi)型的實(shí)例。在 Wire 中,提供者函數(shù)應(yīng)該返回需要?jiǎng)?chuàng)建的實(shí)例,并且可以有任意數(shù)量的輸入?yún)?shù),這些參數(shù)通常表示依賴(lài)項(xiàng)。例如,假設(shè)我們有一個(gè)NewDatabase()函數(shù),用于創(chuàng)建數(shù)據(jù)庫(kù)連接實(shí)例。這個(gè)函數(shù)就是一個(gè)提供者,因?yàn)樗峁┝藬?shù)據(jù)庫(kù)連接實(shí)例。
  2. 注入者(Injectors):注入者是依賴(lài)于提供者所提供的依賴(lài)項(xiàng)的組件。它們通常是結(jié)構(gòu)體或方法,需要依賴(lài)于其他類(lèi)型的實(shí)例來(lái)完成其任務(wù)。在 Wire 中,我們將依賴(lài)注入到注入者中,使其能夠訪(fǎng)問(wèn)所需的依賴(lài)項(xiàng)實(shí)例。例如,假設(shè)我們有一個(gè)UserService結(jié)構(gòu)體,它需要依賴(lài)于數(shù)據(jù)庫(kù)連接實(shí)例來(lái)執(zhí)行數(shù)據(jù)庫(kù)操作。在這種情況下,UserService就是一個(gè)注入者,因?yàn)樗蕾?lài)于提供者所提供的數(shù)據(jù)庫(kù)連接實(shí)例。

在 Wire 中,我們可以通過(guò)定義提供者函數(shù)和注入者結(jié)構(gòu)體來(lái)管理依賴(lài)項(xiàng),并使用 wire.Build() 方法來(lái)自動(dòng)解析和注入依賴(lài)關(guān)系。提供者負(fù)責(zé)創(chuàng)建依賴(lài)項(xiàng)的實(shí)例,而注入者則接受這些實(shí)例并使用它們來(lái)完成其任務(wù),從而實(shí)現(xiàn)了松耦合和可測(cè)試性。

三、Wire 的基本使用方式

使用 Go 語(yǔ)言的 Wire 庫(kù)可以幫助您在依賴(lài)注入時(shí)自動(dòng)解決依賴(lài)關(guān)系。

下面是一個(gè)簡(jiǎn)單的示例,演示了如何在 Go 項(xiàng)目中使用 Wire。

安裝 Wire 庫(kù):

go get github.com/google/wire/cmd/wire

一個(gè)簡(jiǎn)單的 Go 應(yīng)用程序

假設(shè)我們有一個(gè)簡(jiǎn)單的 Go 應(yīng)用程序,其中包含一些服務(wù)和它們的依賴(lài)關(guān)系。

示例代碼:

// services.go
package services

type Database interface {
    Query() string
}

type MySQLDatabase struct{}

func (db *MySQLDatabase) Query() string {
    return "Executing MySQL query"
}

type Service struct {
    DB Database
}

func (s *Service) DoSomething() string {
    return s.DB.Query()
}

使用 Wire 來(lái)定義依賴(lài)注入的配置

示例代碼:

// wire.go
// +build wireinject

package services

import "github.com/google/wire"

func InitializeService() (*Service, error) {
    wire.Build(NewService, NewMySQLDatabase)
    return nil, nil
}

func NewService(db Database) *Service {
    return &Service{
        DB: db,
    }
}

func NewMySQLDatabase() *MySQLDatabase {
    return &MySQLDatabase{}
}

在 wire.Build() 方法中,函數(shù)的參數(shù)順序是有一定要求的,但并不是嚴(yán)格要求的。參數(shù)的順序應(yīng)該遵循依賴(lài)關(guān)系的順序,即依賴(lài)關(guān)系被使用的順序。

在 wire.Build() 方法中,我們可以列出所有的函數(shù),Wire 將會(huì)按照它們的依賴(lài)關(guān)系進(jìn)行排序和解析。當(dāng)然,Wire 有能力理解依賴(lài)關(guān)系并確保它們以正確的順序進(jìn)行構(gòu)建,所以我們并不需要擔(dān)心過(guò)多。

但是,如果代碼中存在循環(huán)依賴(lài)關(guān)系,那么參數(shù)的順序就會(huì)變得重要。在這種情況下,我們需要確保在 wire.Build() 方法中,被循環(huán)依賴(lài)關(guān)系影響的函數(shù)出現(xiàn)在后面的位置,這樣 Wire 才能正確地解析依賴(lài)關(guān)系。

雖然參數(shù)的順序有一定要求,但在大多數(shù)情況下,Wire 能夠自動(dòng)解決依賴(lài)關(guān)系,因此我們不必過(guò)于擔(dān)心參數(shù)的順序問(wèn)題。

使用 Wire 來(lái)自動(dòng)生成依賴(lài)注入的代碼

wire

運(yùn)行以上命令將生成 wire_gen.go 文件,其中包含自動(dòng)生成的代碼。然后,我們可以在應(yīng)用程序中使用 InitializeService 函數(shù)來(lái)初始化服務(wù)。

這只是一個(gè)簡(jiǎn)單的示例,我們可以根據(jù)需求定義更多的服務(wù)和依賴(lài)關(guān)系,并使用 Wire 來(lái)自動(dòng)生成依賴(lài)注入的代碼。

四、代碼詳解

首先,我們解釋 wire.go 文件的代碼。

// +build wireinject

package services

當(dāng)我們創(chuàng)建一個(gè)名為wire.go的文件時(shí),它的用途是告訴 Wire 庫(kù)如何進(jìn)行依賴(lài)注入。

+build wireinject:這是一個(gè)特殊的構(gòu)建標(biāo)記(build tag),它告訴 Go 編譯器,當(dāng)使用 Wire 工具自動(dòng)生成依賴(lài)注入代碼時(shí),應(yīng)該包括這個(gè)文件。這樣可以防止在實(shí)際編譯應(yīng)用程序時(shí)將這個(gè)文件包含進(jìn)去。

import "github.com/google/wire"

導(dǎo)入 Wire 庫(kù),以便在InitializeService函數(shù)中使用 Wire 的構(gòu)建功能。

func InitializeService() (*Service, error) {
    wire.Build(NewService, NewMySQLDatabase)
    return nil, nil
}

InitializeService 函數(shù)是 Wire 的入口。當(dāng)我們運(yùn)行 Wire 命令行工具時(shí),它將檢測(cè)到這個(gè)函數(shù),并使用它來(lái)生成依賴(lài)注入的代碼。該函數(shù)返回 *Service 和 error,但實(shí)際上由于我們?cè)谶@個(gè)示例中沒(méi)有任何錯(cuò)誤檢查,所以總是返回 nil。

wire.Build函數(shù)是 Wire 的核心。它接受一系列函數(shù)作為參數(shù),這些函數(shù)定義了依賴(lài)關(guān)系的創(chuàng)建方式。在這個(gè)例子中,我們傳遞了 NewService 和 NewMySQLDatabase 函數(shù),它們定義了如何創(chuàng)建 Service 和 MySQLDatabase 類(lèi)型的實(shí)例。

func NewService(db Database) *Service {
    return &Service{
        DB: db,
    }
}

NewService 函數(shù)用于創(chuàng)建 Service 類(lèi)型的實(shí)例。它接受一個(gè) Database 類(lèi)型的參數(shù),并返回一個(gè)指向 Service 實(shí)例的指針。在依賴(lài)注入過(guò)程中,Wire 將負(fù)責(zé)提供適當(dāng)類(lèi)型的 Database 實(shí)例作為參數(shù)。

func NewMySQLDatabase() *MySQLDatabase {
    return &MySQLDatabase{}
}

NewMySQLDatabase 函數(shù)用于創(chuàng)建 MySQLDatabase 類(lèi)型的實(shí)例。它簡(jiǎn)單地返回一個(gè)指向 MySQLDatabase 實(shí)例的指針。在實(shí)際應(yīng)用中,可能會(huì)包含更多的邏輯,例如設(shè)置數(shù)據(jù)庫(kù)連接等。

通過(guò)將這些組件組合在一起,wire.go 文件提供了一個(gè)入口,使得 Wire 可以了解應(yīng)該如何創(chuàng)建我們的應(yīng)用程序的依賴(lài)關(guān)系。然后,當(dāng)我們運(yùn)行 Wire 命令行工具時(shí),它將自動(dòng)生成相應(yīng)的依賴(lài)注入代碼。

接下來(lái),我們解釋 wire_gen.go 文件的代碼。

wire_gen.go 文件是由 Wire 工具生成的,其中包含了根據(jù) wire.go 文件中的指令所生成的依賴(lài)注入代碼。

// Code generated by Wire. DO NOT EDIT.
// This file was generated by the "wire" tool (github.com/google/wire).
// Source: wire.go

// Package services provides a wire injector for Service.
package services

這段注釋指出該文件是由 Wire 工具生成的,不應(yīng)手動(dòng)編輯。它還指出了源文件的位置(wire.go)以及生成這個(gè)文件的工具(Wire)。

func InitializeService() (*Service, error) {
    db := NewMySQLDatabase()
    s := NewService(db)
    return s, nil
}

InitializeService 函數(shù)是由 Wire 根據(jù) wire.go 文件中的指令自動(dòng)生成的。它是我們?cè)?nbsp;wire.go 中定義的 InitializeService 函數(shù)的具體實(shí)現(xiàn)。在這里,它簡(jiǎn)單地創(chuàng)建了一個(gè) MySQLDatabase 實(shí)例,并將其傳遞給 NewService 函數(shù)來(lái)創(chuàng)建一個(gè) Service 實(shí)例。

func NewService(db Database) *Service {
    return &Service{
        DB: db,
    }
}

NewService 函數(shù)是我們?cè)?nbsp;wire.go 中定義的 NewService 函數(shù)的具體實(shí)現(xiàn)。它接受一個(gè) Database 類(lèi)型的參數(shù),并返回一個(gè)指向 Service 實(shí)例的指針。在這里,它簡(jiǎn)單地將傳入的 Database 實(shí)例分配給 Service 結(jié)構(gòu)體的 DB 字段。

func NewMySQLDatabase() *MySQLDatabase {
    return &MySQLDatabase{}
}

NewMySQLDatabase 函數(shù)是我們?cè)?nbsp;wire.go 中定義的 NewMySQLDatabase 函數(shù)的具體實(shí)現(xiàn)。它返回一個(gè)指向 MySQLDatabase 實(shí)例的指針。在這里,它簡(jiǎn)單地創(chuàng)建并返回一個(gè)新的 MySQLDatabase 實(shí)例。

這些代碼都是由 Wire 根據(jù) wire.go 文件中的指令自動(dòng)生成的,它們定義了如何創(chuàng)建服務(wù)的實(shí)例以及如何解析它們之間的依賴(lài)關(guān)系。因此,wire_gen.go 文件提供了一個(gè)完整的、可編譯的依賴(lài)注入方案,無(wú)需手動(dòng)編寫(xiě)或管理依賴(lài)關(guān)系的創(chuàng)建代碼。

五、Wire 的高級(jí)特性

除了基本的依賴(lài)注入功能外,Wire 還具有一些高級(jí)特性,使其成為一個(gè)功能強(qiáng)大的依賴(lài)注入框架。以下是 Wire 的一些高級(jí)特性:

  1. Provider Sets:Provider Sets 允許我們將一組相關(guān)的提供者函數(shù)組合成一個(gè)集合,并在需要時(shí)一次性注入到注入者中。這使得依賴(lài)注入的配置更加簡(jiǎn)潔和可組織,并且可以幫助提高代碼的可讀性和可維護(hù)性。
  2. Set Functions:Set Functions 是一種用于將提供者函數(shù)組織成可重用的集合的方式。它們類(lèi)似于 Provider Sets,但提供了更靈活的組織和使用方式。我們可以使用Set函數(shù)定義一組提供者函數(shù),并將這些集合傳遞給 wire.Build() 方法,以便 Wire 可以識(shí)別和解析其中包含的提供者函數(shù)。
  3. Interface Binding:Wire 支持將接口綁定到實(shí)現(xiàn)類(lèi)型。這意味著您可以定義接口和實(shí)現(xiàn)類(lèi)型,并將它們綁定在一起,從而使得在需要接口類(lèi)型的實(shí)例時(shí),Wire 能夠自動(dòng)為我們提供正確的實(shí)現(xiàn)類(lèi)型。這樣可以提高代碼的靈活性和可測(cè)試性。
  4. Custom Wire Functions:我們可以編寫(xiě)自定義 Wire 函數(shù)來(lái)執(zhí)行特定的依賴(lài)注入邏輯。這使得我們可以根據(jù)我們的應(yīng)用程序的需求來(lái)定制 Wire 的行為,并添加一些自定義的處理邏輯。例如,我們可以編寫(xiě)一個(gè)自定義的 Wire 函數(shù)來(lái)處理特定類(lèi)型的依賴(lài)項(xiàng),或者執(zhí)行一些額外的驗(yàn)證和處理。
  5. Provider Bindings:Provider Bindings 允許我們將提供者函數(shù)綁定到接口或結(jié)構(gòu)體上。這樣,當(dāng)我們需要某個(gè)接口類(lèi)型的實(shí)例時(shí),Wire 將自動(dòng)為我們提供正確的提供者函數(shù)。這提高了代碼的靈活性,并使得依賴(lài)注入更加方便和易用。

這些高級(jí)特性使得 Wire 成為一個(gè)功能豐富且靈活的依賴(lài)注入框架,可以滿(mǎn)足不同類(lèi)型的應(yīng)用程序的需求,并幫助提高代碼的質(zhì)量、可維護(hù)性和可測(cè)試性。

限于篇幅,我們介紹其中 2 個(gè)高級(jí)特性,Provider Sets 和 Set Functions。

Provider Sets :我們把之前的示例改寫(xiě)成使用 Provider Sets 的方式:

// wire.go

// +build wireinject

package services

import "github.com/google/wire"

// 定義 Provider Set
var ProviderSet = wire.NewSet(NewService, NewMySQLDatabase)

// InitializeService 使用 Provider Set 創(chuàng)建服務(wù)實(shí)例
func InitializeService() (*Service, error) {
 wire.Build(ProviderSet)
 return nil, nil
}

// NewService 是 Service 的提供者函數(shù)
func NewService(db Database) *Service {
 return &Service{
  DB: db,
 }
}

// NewMySQLDatabase 是 MySQLDatabase 的提供者函數(shù)
func NewMySQLDatabase() *MySQLDatabase {
 return &MySQLDatabase{}
}

在這個(gè)修改后的 wire.go 文件中,我們定義了一個(gè) ProviderSet,其中包含了兩個(gè)提供者函數(shù):NewService 和 NewMySQLDatabase。然后,在 InitializeService 函數(shù)中,我們使用 ProviderSet 來(lái)構(gòu)建服務(wù)實(shí)例。這樣,我們可以更清晰地組織和管理提供者函數(shù),并確保它們?cè)谝蕾?lài)注入過(guò)程中被正確地使用。

使用 Provider Sets 的情況可以歸納如下:

  1. 組織提供者函數(shù):如果我們有多個(gè)提供者函數(shù),而它們之間有一定的相關(guān)性或邏輯關(guān)系,那么使用 Provider Sets 可以更好地組織這些提供者函數(shù)。Provider Sets 允許我們將相關(guān)的提供者函數(shù)組合成一個(gè)集合,使得代碼更具可讀性和可維護(hù)性。
  2. 復(fù)用提供者函數(shù):如果我們的應(yīng)用程序中存在一些通用的提供者函數(shù),可以在多個(gè)地方進(jìn)行復(fù)用,那么使用 Provider Sets 可以更方便地管理和使用這些提供者函數(shù)。通過(guò)將這些提供者函數(shù)放入 Provider Set 中,我們可以在需要時(shí)直接使用該集合,并且可以輕松地將其注入到不同的注入者中。
  3. 簡(jiǎn)化依賴(lài)注入配置:對(duì)于復(fù)雜的依賴(lài)注入配置,使用 Provider Sets 可以幫助簡(jiǎn)化配置過(guò)程。通過(guò)將一組相關(guān)的提供者函數(shù)組合成 Provider Set,并在需要時(shí)直接使用該集合,可以減少配置代碼的復(fù)雜性和重復(fù)性。
  4. 提高代碼的可測(cè)試性和可維護(hù)性:使用 Provider Sets 可以使代碼更具可測(cè)試性和可維護(hù)性。通過(guò)將提供者函數(shù)組織成 Provider Set,并將其作為一個(gè)整體注入到注入者中,可以更容易地進(jìn)行單元測(cè)試和代碼重構(gòu),從而提高代碼的質(zhì)量和可維護(hù)性。

當(dāng)我們有多個(gè)相關(guān)的提供者函數(shù)需要管理和使用時(shí),或者希望簡(jiǎn)化復(fù)雜的依賴(lài)注入配置時(shí),可以考慮使用 Provider Sets。它可以幫助我們更好地組織和管理提供者函數(shù),從而提高代碼的可讀性、可維護(hù)性和可測(cè)試性。

Set Functions:

Set Functions 是 Wire 中的一種功能,用于組織提供者函數(shù)并創(chuàng)建可重用的集合。使用 Set Functions 可以將一組相關(guān)的提供者函數(shù)組合成一個(gè)集合,從而簡(jiǎn)化依賴(lài)注入的配置和管理。讓我詳細(xì)解釋一下如何使用 Set Functions:

  • 創(chuàng)建 Set Functions:首先,您需要?jiǎng)?chuàng)建一個(gè) Set Functions,其中包含一組提供者函數(shù)。每個(gè)提供者函數(shù)都會(huì)返回一個(gè)實(shí)例,并且通常表示一種依賴(lài)項(xiàng)的創(chuàng)建方式。
package services

import "github.com/google/wire"

// 定義一個(gè) Set 函數(shù),包含一組提供者函數(shù)
var ServiceSet = wire.NewSet(NewService, NewDatabase)

在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為 ServiceSet 的 Set Functions,其中包含了兩個(gè)提供者函數(shù):NewService 和 NewDatabase。這些提供者函數(shù)用于創(chuàng)建 Service 和 Database 實(shí)例。

  • 使用 Set Functions:然后,您可以在wire.Build()方法中使用這個(gè) Set Functions,以便 Wire 可以識(shí)別和解析這些提供者函數(shù)。
package services

import "github.com/google/wire"

// 使用Set函數(shù)來(lái)配置依賴(lài)注入
func InitializeService() (*Service, error) {
    wire.Build(ServiceSet)
    return nil, nil
}

在這個(gè)例子中,我們?cè)?nbsp;InitializeService 函數(shù)中使用了 ServiceSet 函數(shù),以便 Wire 可以識(shí)別并解析其中包含的提供者函數(shù)。這樣,我們就可以在需要時(shí)直接使用這個(gè)集合,并且可以輕松地將其注入到不同的注入者中。

Set Functions 使得組織和管理提供者函數(shù)變得更加簡(jiǎn)單和靈活,可以幫助我們更好地管理依賴(lài)注入的配置,提高代碼的可讀性和可維護(hù)性。

六、總結(jié)

Wire 是一個(gè)基于 Go 語(yǔ)言的依賴(lài)注入(DI)框架,它旨在簡(jiǎn)化和自動(dòng)化 Go 應(yīng)用程序中的依賴(lài)項(xiàng)管理和注入過(guò)程。通過(guò)使用 Wire,我們可以更輕松地管理應(yīng)用程序中的依賴(lài)關(guān)系,并將它們注入到相應(yīng)的組件中,從而實(shí)現(xiàn)松耦合和更易于測(cè)試的代碼。

Wire 的主要特點(diǎn)和功能包括:

  1. 自動(dòng)化依賴(lài)注入:Wire 可以自動(dòng)解析和注入依賴(lài)關(guān)系,無(wú)需手動(dòng)編寫(xiě)繁瑣的依賴(lài)注入代碼。我們只需定義提供者函數(shù)和注入者結(jié)構(gòu)體,Wire 將負(fù)責(zé)解析依賴(lài)關(guān)系并生成相應(yīng)的注入代碼。
  2. 類(lèi)型安全:Wire 是一個(gè)靜態(tài)類(lèi)型檢查的依賴(lài)注入框架,它能夠在編譯時(shí)檢測(cè)到依賴(lài)關(guān)系中的錯(cuò)誤,并提供相應(yīng)的錯(cuò)誤提示。這可以幫助我們?cè)陂_(kāi)發(fā)過(guò)程中及早發(fā)現(xiàn)和解決問(wèn)題,提高代碼的健壯性和可維護(hù)性。
  3. 簡(jiǎn)潔明了:Wire 的使用方式簡(jiǎn)單明了,無(wú)需復(fù)雜的配置或?qū)W習(xí)曲線(xiàn)。我們只需在代碼中定義提供者函數(shù)和注入者結(jié)構(gòu)體,然后使用 Wire 工具生成相應(yīng)的依賴(lài)注入代碼即可。
  4. 靈活可擴(kuò)展:Wire 提供了豐富的功能和選項(xiàng),可以滿(mǎn)足不同類(lèi)型應(yīng)用程序的需求。我們可以使用 Provider Sets、Set Functions 等功能來(lái)組織和管理依賴(lài)關(guān)系,從而實(shí)現(xiàn)更靈活、可擴(kuò)展的依賴(lài)注入方案。

Wire 是一個(gè)強(qiáng)大而簡(jiǎn)單的依賴(lài)注入框架,它可以幫助我們更輕松地管理和注入依賴(lài)關(guān)系,從而提高代碼的質(zhì)量、可維護(hù)性和可測(cè)試性。

參考資料:[1]Wire: https://github.com/google/wire

責(zé)任編輯:武曉燕 來(lái)源: Golang語(yǔ)言開(kāi)發(fā)棧
相關(guān)推薦

2022-09-30 15:31:21

Golang開(kāi)發(fā)工具

2024-05-06 13:34:28

WireGoogleGo

2024-04-01 00:02:56

Go語(yǔ)言代碼

2021-07-07 10:48:00

DigGoWire

2023-12-09 14:29:30

編程語(yǔ)言Go

2022-12-29 08:54:53

依賴(lài)注入JavaScript

2023-11-06 08:14:51

Go語(yǔ)言Context

2015-09-02 11:22:36

JavaScript實(shí)現(xiàn)思路

2021-09-02 07:04:44

Go 開(kāi)發(fā)利器

2011-05-31 10:00:21

Android Spring 依賴(lài)注入

2023-07-11 09:14:12

Beanquarkus

2022-04-11 09:02:18

Swift依賴(lài)注

2014-07-08 14:05:48

DaggerAndroid依賴(lài)

2017-08-16 16:00:05

PHPcontainer依賴(lài)注入

2024-12-30 12:00:00

.NET Core依賴(lài)注入屬性注入

2012-10-08 09:25:59

GoGo語(yǔ)言開(kāi)發(fā)語(yǔ)言

2018-03-12 22:13:46

GO語(yǔ)言編程軟件

2021-07-25 21:13:50

框架Angular開(kāi)發(fā)

2016-03-21 17:08:54

Java Spring注解區(qū)別

2016-12-28 09:30:37

Andriod安卓平臺(tái)依賴(lài)注入
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)