最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go語(yǔ)言Pflag Viper Cobra 核心功能使用介紹

 更新時(shí)間:2022年09月16日 09:52:14   作者:阿璐4r  
這篇文章主要為大家介紹了go語(yǔ)言Pflag Viper Cobra 核心功能使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1.如何構(gòu)建應(yīng)用框架

一般來(lái)說(shuō)構(gòu)建應(yīng)用框架包含3個(gè)部分:

  • 命令行參數(shù)解析
  • 配置文件解析
  • 應(yīng)用的命令行框架:需要具備 Help 功能、需要能夠解析命令行參數(shù)和配置文件、命令需要能夠初始化業(yè)務(wù)代碼,并最終啟動(dòng)業(yè)務(wù)進(jìn)程 上3個(gè)需求便涉及Pflag、Viper、Cobra的使用,并且這三個(gè)包也是相互聯(lián)系滴

2.命令行參數(shù)解析工具:Pflag

雖然 Go 源碼中提供了一個(gè)標(biāo)準(zhǔn)庫(kù) Flag 包,用來(lái)對(duì)命令行參數(shù)進(jìn)行解析,但在大型項(xiàng)目中應(yīng)用更廣泛的是另外一個(gè)包:Pflag

2.1 Pflag 包 Flag 定義

Pflag 可以對(duì)命令行參數(shù)進(jìn)行處理,一個(gè)命令行參數(shù)在 Pflag 包中會(huì)解析為一個(gè) Flag 類型的變量

type Flag struct {
    Name                string // flag長(zhǎng)選項(xiàng)的名稱
    Shorthand           string // flag短選項(xiàng)的名稱,一個(gè)縮寫的字符
    Usage               string // flag的使用文本
    Value               Value  // flag的值
    DefValue            string // flag的默認(rèn)值
    Changed             bool // 記錄flag的值是否有被設(shè)置過(guò)
    NoOptDefVal         string // 當(dāng)flag出現(xiàn)在命令行,但是沒(méi)有指定選項(xiàng)值時(shí)的默認(rèn)值
    Deprecated          string // 記錄該flag是否被放棄
    Hidden              bool // 如果值為true,則從help/usage輸出信息中隱藏該flag
    ShorthandDeprecated string // 如果flag的短選項(xiàng)被廢棄,當(dāng)使用flag的短選項(xiàng)時(shí)打印該信息
    Annotations         map[string][]string // 給flag設(shè)置注解
}

Flag 的值是一個(gè) Value 類型的接口,Value 定義如下

type Value interface {
    String() string // 將flag類型的值轉(zhuǎn)換為string類型的值,并返回string的內(nèi)容
    Set(string) error // 將string類型的值轉(zhuǎn)換為flag類型的值,轉(zhuǎn)換失敗報(bào)錯(cuò)
    Type() string // 返回flag的類型,例如:string、int、ip等
}

2.2 Pflag 包 FlagSet 定義

Pflag 除了支持單個(gè)的 Flag 之外,還支持 FlagSet。FlagSet 是一些預(yù)先定義好的 Flag 的集合

  • 調(diào)用 NewFlagSet 創(chuàng)建一個(gè) FlagSet
  • 使用 Pflag 包定義的全局 FlagSet:CommandLine
var version bool
flagSet := pflag.NewFlagSet("test", pflag.ContinueOnError)
flagSet.BoolVar(&version, "version", true, "Print version information and quit.")
=================================
import (
    "github.com/spf13/pflag"
)
pflag.BoolVarP(&version, "version", "v", true, "Print version information and quit.")
func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
    flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)
    flag.NoOptDefVal = "true"
}

2.3 Pflag 使用方法

  • 支持多種命令行參數(shù)定義方式
// 支持長(zhǎng)選項(xiàng)、默認(rèn)值和使用文本,并將標(biāo)志的值存儲(chǔ)在指針中。
var name = pflag.String("name", "colin", "Input Your Name")
// 支持長(zhǎng)選項(xiàng)、短選項(xiàng)、默認(rèn)值和使用文本,并將標(biāo)志的值存儲(chǔ)在指針中
var name = pflag.StringP("name", "n", "colin", "Input Your Name")
// 支持長(zhǎng)選項(xiàng)、默認(rèn)值和使用文本,并將標(biāo)志的值綁定到變量。
var name string
pflag.StringVar(&name, "name", "colin", "Input Your Name")
// 支持長(zhǎng)選項(xiàng)、短選項(xiàng)、默認(rèn)值和使用文本,并將標(biāo)志的值綁定到變量。
var name string
pflag.StringVarP(&name, "name", "n","colin", "Input Your Name")
// 函數(shù)名帶Var說(shuō)明是將標(biāo)志的值綁定到變量,否則是將標(biāo)志的值存儲(chǔ)在指針中
// 函數(shù)名帶P說(shuō)明支持短選項(xiàng),否則不支持短選項(xiàng)。
  • 使用Get獲取參數(shù)的值。
i, err := flagset.GetInt("flagname")
  • 獲取非選項(xiàng)參數(shù)。
package main
import (
    "fmt"
    "github.com/spf13/pflag"
)
var (
    flagvar = pflag.Int("flagname", 1234, "help message for flagname")
)
// 在定義完標(biāo)志之后,可以調(diào)用pflag.Parse()來(lái)解析定義的標(biāo)志。解析后,可通過(guò)pflag.Args()返回所有的非選項(xiàng)參數(shù),通過(guò)pflag.Arg(i)返回第 i 個(gè)非選項(xiàng)參數(shù)。參數(shù)下標(biāo) 0 到 pflag.NArg() - 1。
func main() {
    pflag.Parse()
    fmt.Printf("argument number is: %v\n", pflag.NArg())
    fmt.Printf("argument list is: %v\n", pflag.Args())
    fmt.Printf("the first argument is: %v\n", pflag.Arg(0))
}
  • 指定了選項(xiàng)但是沒(méi)有指定選項(xiàng)值時(shí)的默認(rèn)值。
var ip = pflag.IntP("flagname", "f", 1234, "help message")
pflag.Lookup("flagname").NoOptDefVal = "4321"
--flagname=1357 ==> 1357
--flagname ==> 4321
[nothing] ==> 1234
  • 棄用標(biāo)志或者標(biāo)志的簡(jiǎn)寫
// deprecate a flag by specifying its name and a usage message
pflag.CommandLine.MarkDeprecated("logmode", "please use --log-mode instead")
  • 保留名為 port 的標(biāo)志,但是棄用它的簡(jiǎn)寫形式
pflag.IntVarP(&port, "port", "P", 3306, "MySQL service host port.")
// deprecate a flag shorthand by specifying its flag name and a usage message
pflag.CommandLine.MarkShorthandDeprecated("port", "please use --port only")
  • 隱藏標(biāo)志。
// 可以將 Flag 標(biāo)記為隱藏的,這意味著它仍將正常運(yùn)行,但不會(huì)顯示在 usage/help 文本中。
// hide a flag by specifying its name
pflag.CommandLine.MarkHidden("secretFlag")

3.配置解析神器:Viper

幾乎所有的后端服務(wù),都需要一些配置項(xiàng)來(lái)配置我們的服務(wù);Viper 是 Go 應(yīng)用程序現(xiàn)代化的、完整的解決方案,能夠處理不同格式的配置文件 Viper 可以從不同的位置讀取配置,不同位置的配置具有不同的優(yōu)先級(jí):

  • 通過(guò) viper.Set 函數(shù)顯示設(shè)置的配置
  • 命令行參數(shù)
  • 環(huán)境變量
  • 配置文件
  • Key/Value 存儲(chǔ)
  • 默認(rèn)值

3.1讀入配置

讀入配置,就是將配置讀入到 Viper 中,有如下讀入方式:

  • 設(shè)置默認(rèn)值。
// 當(dāng)沒(méi)有通過(guò)配置文件、環(huán)境變量、遠(yuǎn)程配置或命令行標(biāo)志設(shè)置 key 時(shí),設(shè)置默認(rèn)值通常是很有用的
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
  • 讀取配置文件
package main
import (
  "fmt"
  "github.com/spf13/pflag"
  "github.com/spf13/viper"
)
var (
  cfg  = pflag.StringP("config", "c", "", "Configuration file.")
  help = pflag.BoolP("help", "h", false, "Show this help message.")
)
func main() {
  pflag.Parse()
  if *help {
    pflag.Usage()
    return
  }
  // 從配置文件中讀取配置
  if *cfg != "" {
    viper.SetConfigFile(*cfg)   // 指定配置文件名
    viper.SetConfigType("yaml") // 如果配置文件名中沒(méi)有文件擴(kuò)展名,則需要指定配置文件的格式,告訴viper以何種格式解析文件
  } else {
    viper.AddConfigPath(".")          // 把當(dāng)前目錄加入到配置文件的搜索路徑中
    viper.AddConfigPath("$HOME/.iam") // 配置文件搜索路徑,可以設(shè)置多個(gè)配置文件搜索路徑
    viper.SetConfigName("config")     // 配置文件名稱(沒(méi)有文件擴(kuò)展名)
  }
  if err := viper.ReadInConfig(); err != nil { // 讀取配置文件。如果指定了配置文件名,則使用指定的配置文件,否則在注冊(cè)的搜索路徑中搜索
    panic(fmt.Errorf("Fatal error config file: %s \n", err))
  }
  fmt.Printf("Used configuration file is: %s\n", viper.ConfigFileUsed())
}
  • 監(jiān)聽和重新讀取配置文件。 Viper 支持在運(yùn)行時(shí)讓應(yīng)用程序?qū)崟r(shí)讀取配置文件,也就是熱加載配置
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
   // 配置文件發(fā)生變更之后會(huì)調(diào)用的回調(diào)函數(shù)
  fmt.Println("Config file changed:", e.Name)
})
//不建議在實(shí)際開發(fā)中使用熱加載功能,因?yàn)榧词古渲脽峒虞d了,程序中的代碼也不一定會(huì)熱加載。例如:修改了服務(wù)監(jiān)聽端口,但是服務(wù)沒(méi)有重啟,這時(shí)候服務(wù)還是監(jiān)聽在老的端口上,會(huì)造成不一致
  • 設(shè)置配置值
// 可以通過(guò) viper.Set() 函數(shù)來(lái)顯式設(shè)置配置:
viper.Set("user.username", "colin")
  • 使用環(huán)境變量
// 使用環(huán)境變量
os.Setenv("VIPER_USER_SECRET_ID", "QLdywI2MrmDVjSSv6e95weNRvmteRjfKAuNV")
os.Setenv("VIPER_USER_SECRET_KEY", "bVix2WBv0VPfrDrvlLWrhEdzjLpPCNYb")
viper.AutomaticEnv()                                             // 讀取環(huán)境變量
viper.SetEnvPrefix("VIPER")                                      // 設(shè)置環(huán)境變量前綴:VIPER_,如果是viper,將自動(dòng)轉(zhuǎn)變?yōu)榇髮憽?
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) // 將viper.Get(key) key字符串中'.'和'-'替換為'_'
viper.BindEnv("user.secret-key")
viper.BindEnv("user.secret-id", "USER_SECRET_ID") // 綁定環(huán)境變量名到key
  • 使用標(biāo)志 Viper 支持 Pflag 包,能夠綁定 key 到 Flag。與 BindEnv 類似,在調(diào)用綁定方法時(shí),不會(huì)設(shè)置該值,但在訪問(wèn)它時(shí)會(huì)設(shè)置。
viper.BindPFlag("token", pflag.Lookup("token")) // 綁定單個(gè)標(biāo)志
viper.BindPFlags(pflag.CommandLine)             //綁定標(biāo)志集

3.2 讀取配置

  • 訪問(wèn)嵌套的鍵。
{
    "host": {
        "address": "localhost",
        "port": 5799
    },
    "datastore": {
        "metric": {
            "host": "127.0.0.1",
            "port": 3099
        },
        "warehouse": {
            "host": "198.0.0.1",
            "port": 2112
        }
    }
}
viper.GetString("datastore.metric.host") // (返回 "127.0.0.1")
  • 反序列化 Viper 可以支持將所有或特定的值解析到結(jié)構(gòu)體、map 等。可以通過(guò)兩個(gè)函數(shù)來(lái)實(shí)現(xiàn):
type config struct {
  Port int
  Name string
  PathMap string `mapstructure:"path_map"`
}
var C config
err := viper.Unmarshal(&C)
if err != nil {
  t.Fatalf("unable to decode into struct, %v", err)
}

Viper 在后臺(tái)使用github.com/mitchellh/mapstructure來(lái)解析值,其默認(rèn)情況下使用mapstructure tags。當(dāng)我們需要將 Viper 讀取的配置反序列到我們定義的結(jié)構(gòu)體變量中時(shí),一定要使用 mapstructure tags

  • 序列化成字符串
import (
    yaml "gopkg.in/yaml.v2"
    // ...
)
func yamlStringSettings() string {
    c := viper.AllSettings()
    bs, err := yaml.Marshal(c)
    if err != nil {
        log.Fatalf("unable to marshal config to YAML: %v", err)
    }
    return string(bs)
}

4.現(xiàn)代化的命令行框架:Cobra

Cobra 既是一個(gè)可以創(chuàng)建強(qiáng)大的現(xiàn)代 CLI 應(yīng)用程序的庫(kù),也是一個(gè)可以生成應(yīng)用和命令文件的程序 應(yīng)用程序通常遵循如下模式:APPNAME VERB NOUN --ADJECTIVE或者APPNAME COMMAND ARG --FLAG VERB 代表動(dòng)詞,NOUN 代表名詞,ADJECTIVE 代表形容詞

4.1 使用 Cobra 庫(kù)創(chuàng)建命令

  • 創(chuàng)建 rootCmd
$ mkdir -p newApp2 && cd newApp2
// 通常情況下,我們會(huì)將 rootCmd 放在文件 cmd/root.go 中。
var rootCmd = &cobra.Command{
  Use:   "hugo",
  Short: "Hugo is a very fast static site generator",
  Long: `A Fast and Flexible Static Site Generator built with
                love by spf13 and friends in Go.
                Complete documentation is available at http://hugo.spf13.com`,
  Run: func(cmd *cobra.Command, args []string) {
    // Do Stuff Here
  },
}
func Execute() {
  if err := rootCmd.Execute(); err != nil {
    fmt.Println(err)
    os.Exit(1)
  }
}
// 還可以在 init() 函數(shù)中定義標(biāo)志和處理配置
import (
  "fmt"
  "os"
  homedir "github.com/mitchellh/go-homedir"
  "github.com/spf13/cobra"
  "github.com/spf13/viper"
)
var (
    cfgFile     string
    projectBase string
    userLicense string
)
func init() {
  cobra.OnInitialize(initConfig)
  rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
  rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
  rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
  rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
  rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
  viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
  viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
  viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
  viper.SetDefault("license", "apache")
}
func initConfig() {
  // Don't forget to read config either from cfgFile or from home directory!
  if cfgFile != "" {
    // Use config file from the flag.
    viper.SetConfigFile(cfgFile)
  } else {
    // Find home directory.
    home, err := homedir.Dir()
    if err != nil {
      fmt.Println(err)
      os.Exit(1)
    }
    // Search config in home directory with name ".cobra" (without extension).
    viper.AddConfigPath(home)
    viper.SetConfigName(".cobra")
  }
  if err := viper.ReadInConfig(); err != nil {
    fmt.Println("Can't read config:", err)
    os.Exit(1)
  }
}
  • 創(chuàng)建 main.go 我們還需要一個(gè) main 函數(shù)來(lái)調(diào)用 rootCmd,通常我們會(huì)創(chuàng)建一個(gè) main.go 文件,在 main.go 中調(diào)用 rootCmd.Execute() 來(lái)執(zhí)行命令
package main
import (
  "{pathToYourApp}/cmd"
)
func main() {
  cmd.Execute()
}
  • 添加命令 通常情況下,我們會(huì)把其他命令的源碼文件放在 cmd/ 目錄下,例如,我們添加一個(gè) version 命令,可以創(chuàng)建 cmd/version.go 文件
package cmd
import (
  "fmt"
  "github.com/spf13/cobra"
)
func init() {
  rootCmd.AddCommand(versionCmd)
}
var versionCmd = &cobra.Command{
  Use:   "version",
  Short: "Print the version number of Hugo",
  Long:  `All software has versions. This is Hugo's`,
  Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
  },
}
  • 編譯并運(yùn)行
$ go mod init github.com/marmotedu/gopractise-demo/cobra/newApp2
$ go build -v .
$ ./newApp2 -h
A Fast and Flexible Static Site Generator built with
love by spf13 and friends in Go.
Complete documentation is available at http://hugo.spf13.com
Usage:
hugo [flags]
hugo [command]
Available Commands:
help Help about any command
version Print the version number of Hugo
Flags:
-a, --author string Author name for copyright attribution (default "YOUR NAME")
--config string config file (default is $HOME/.cobra.yaml)
-h, --help help for hugo
-l, --license licensetext Name of license for the project (can provide licensetext in config)
-b, --projectbase string base project directory eg. github.com/spf13/
--viper Use Viper for configuration (default true)
 Use "hugo [command] --help" for more information about a command.

4.2使用標(biāo)志

Cobra 可以跟 Pflag 結(jié)合使用,實(shí)現(xiàn)強(qiáng)大的標(biāo)志功能

// 使用持久化的標(biāo)志
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
// 分配一個(gè)本地標(biāo)志,本地標(biāo)志只能在它所綁定的命令上使用
rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
// 將標(biāo)志綁定到 Viper
var author string
func init() {
 rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
 viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
}
// 設(shè)置標(biāo)志為必選
rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
rootCmd.MarkFlagRequired("region")

5.總結(jié)

在開發(fā) Go 項(xiàng)目時(shí),我們可以通過(guò) Pflag 來(lái)解析命令行參數(shù),通過(guò) Viper 來(lái)解析配置文件,用 Cobra 來(lái)實(shí)現(xiàn)命令行框架。

你可以通過(guò) pflag.String()、 pflag.StringP()、pflag.StringVar()、pflag.StringVarP() 方法來(lái)設(shè)置命令行參數(shù),并使用 Get 來(lái)獲取參數(shù)的值

以上就是go語(yǔ)言Pflag Viper Cobra 核心功能使用介紹的詳細(xì)內(nèi)容,更多關(guān)于Go語(yǔ)言Pflag Viper Cobra功能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語(yǔ)言中最便捷的http請(qǐng)求包resty的使用詳解

    Go語(yǔ)言中最便捷的http請(qǐng)求包resty的使用詳解

    go語(yǔ)言雖然自身就有net/http包,但是說(shuō)實(shí)話用起來(lái)沒(méi)那么好用,resty包是go語(yǔ)言中一個(gè)非常受歡迎的http請(qǐng)求處理包,下面我們一起來(lái)學(xué)習(xí)一下resty的具體使用吧
    2025-03-03
  • Golang接口的定義與空接口及斷言的使用示例

    Golang接口的定義與空接口及斷言的使用示例

    在?Golang?中,接口是一種類型,它是由一組方法簽名組成的抽象集合。這篇文章主要為大家介紹了Golang接口的具體使用,希望對(duì)大家有所幫助,空接口是特殊形式的接口類型,普通的接口都有方法,而空接口沒(méi)有定義任何方法口,也因此,我們可以說(shuō)所有類型都至少實(shí)現(xiàn)了空接口
    2023-04-04
  • Go語(yǔ)言map實(shí)現(xiàn)順序讀取

    Go語(yǔ)言map實(shí)現(xiàn)順序讀取

    當(dāng)我們遍歷 map 時(shí),那就是輸出的鍵值對(duì)順序是不確定的,本文主要介紹了Go語(yǔ)言map實(shí)現(xiàn)順序讀取, 文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Go語(yǔ)言基礎(chǔ)切片的創(chuàng)建及初始化示例詳解

    Go語(yǔ)言基礎(chǔ)切片的創(chuàng)建及初始化示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)切片的創(chuàng)建及初始化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-11-11
  • Golang中map的深入探究

    Golang中map的深入探究

    Go中Map是一個(gè)KV對(duì)集合,下面這篇文章主要給大家介紹了關(guān)于Golang中map探究的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-09-09
  • 重學(xué)Go語(yǔ)言之運(yùn)算符與控制結(jié)構(gòu)詳解

    重學(xué)Go語(yǔ)言之運(yùn)算符與控制結(jié)構(gòu)詳解

    對(duì)于任何編程語(yǔ)言來(lái)說(shuō),運(yùn)算符和控制結(jié)構(gòu)都算是最基礎(chǔ)的知識(shí)了,既然是基礎(chǔ),當(dāng)然非常有必要學(xué)習(xí),因此在這篇文章中我們就來(lái)討論一下
    2023-02-02
  • Go web入門Go pongo2模板引擎

    Go web入門Go pongo2模板引擎

    這篇文章主要為大家介紹了Go web編程入門Go pongo2模板引擎使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 基于Go語(yǔ)言實(shí)現(xiàn)冒泡排序算法

    基于Go語(yǔ)言實(shí)現(xiàn)冒泡排序算法

    冒泡排序是交換排序中最簡(jiǎn)單的一種算法。這篇文章將利用Go語(yǔ)言實(shí)現(xiàn)冒泡排序算法,文中的示例代碼講解詳細(xì),對(duì)學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考一下
    2022-12-12
  • IdeaGo啟動(dòng)報(bào)錯(cuò)Failed to create JVM的問(wèn)題解析

    IdeaGo啟動(dòng)報(bào)錯(cuò)Failed to create JVM的問(wèn)題解析

    這篇文章主要介紹了IdeaGo啟動(dòng)報(bào)錯(cuò)Failed to create JVM的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 如何使用Go檢測(cè)用戶本地是否安裝chrome

    如何使用Go檢測(cè)用戶本地是否安裝chrome

    這篇文章主要為大家詳細(xì)介紹了如何使用Go檢測(cè)用戶本地是否安裝chrome,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-10-10

最新評(píng)論

嵊州市| 南木林县| 平舆县| 合作市| 博湖县| 怀安县| 阿拉善盟| 姜堰市| 延川县| 康马县| 辛集市| 张掖市| 五台县| 四会市| 舞阳县| 蕲春县| 湖北省| 瑞金市| 沾益县| 清新县| 嵊州市| 印江| 宾川县| 哈密市| 小金县| 孝昌县| 双城市| 庆安县| 邢台县| 文山县| 抚远县| 尖扎县| 阿尔山市| 绥中县| 青海省| 江永县| 文化| 翁源县| 四子王旗| 晋宁县| 西宁市|