如何在Go中使用命令参数?

如何在Go中使用命令参数?,go,command-line-arguments,Go,Command Line Arguments,我刚开始学习Go,我使用ProbablyPrime库编写了一个prime测试程序 package main import ( "fmt" "math/big" "math" "os" "strconv" ) func prime_test(n int64, certainty int)(bool,float64){ var probobility float64 i := big.NewInt(n) isPrime := i.P

我刚开始学习Go,我使用
ProbablyPrime
库编写了一个prime测试程序

package main

import (
    "fmt"
    "math/big"
    "math"
    "os"
    "strconv"
)

func prime_test(n int64, certainty int)(bool,float64){
    var probobility float64
    i := big.NewInt(n)
    isPrime := i.ProbablyPrime(certainty)
    probobility = 1 - 1/math.Pow(4,10)
    return isPrime, probobility
}

func why_not_prime(n int64)(int64){
    var i int64 
    for  i=2 ; i<n/2; i++ {
        if n%i == 0 {return i}
    }
    return i
}


func main() {
    var n int64
    var certainty int
    var isPrime bool
    var probobility float64 

    if len(os.Args) > 1 {
    n,_ = strconv.ParseInt(os.Args[1],64,64)
    certainty,_ = strconv.Atoi(os.Args[2])
    }

    isPrime, probobility = prime_test(n,certainty)
    if isPrime {
        fmt.Printf("%d is probably %0.8f%% a prime.", n, probobility*100)
    } else {
        var i int64
        i = why_not_prime(n)
        fmt.Printf("%d is a composite because it can be divided by %d", n, i)
    }
}
主程序包
进口(
“fmt”
“数学/大”
“数学”
“操作系统”
“strconv”
)
func素数检验(n int64,确定性int)(bool,float64){
变量概率
i:=big.NewInt(n)
isPrime:=i.ProbablyPrime(确定性)
概率=1-1/数学功率(4,10)
返回i优先级、概率
}
func为什么不素数(n int64)(int64){
var i int64
对于i=2;i=1{
n、 _u=strconv.ParseInt(os.Args[1],64,64)
确定性,即strconv.Atoi(os.Args[2])
}
isPrime,概率=素数检验(n,确定性)
如果是isPrime{
fmt.Printf(“%d可能是%0.8f%%素数。”,n,概率*100)
}否则{
var i int64
i=为什么不素数(n)
fmt.Printf(“%d是复合的,因为它可以被%d除”,n,i)
}
}
代码可以成功编译。当我运行它时,它总是返回
0是一个复合值,因为它可以被2除


我猜命令行参数解析有问题。如何修复它?

问题在于这一行:

n,_ = strconv.ParseInt(os.Args[1],64,64)
各国的文件:

ParseInt解释给定基(2到36)中的字符串s,并返回相应的值i

基数最多可以是
36
,您通过
64
。在这种情况下,将返回一个错误(使用空白标识符<代码> <代码> >丢弃,并且<代码> n< /代码>将具有“<代码> 0 < /COD>”的零值,因此您将输出视为

0是一个组合,因为它可以被2除

解决方案:

将相关行更改为:

n, _ = strconv.ParseInt(os.Args[1], 10, 64)
它应该会起作用。此外,您不应该放弃错误,因为您将遇到类似的情况。而是像这样正确地处理它们:

var err error
n, err = strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
    log.Fatal(err)
}
注意:

还要注意,第一个参数(
os.Args[0]
是可执行文件的名称),由于您需要并使用两个额外的参数,因此应检查
os.Args
的长度是否大于2而不是1:

if len(os.Args) > 2 {
    // os.Args[1] and os.Args[2] is valid
}

我的猜测是
len(os.Args)
不大于1,这就是为什么
n
没有被设置为除
0
之外的任何值。我会在
if
语句中插入一条print语句,以检查是否是这种情况。@SelectricSimian谢谢。我把
fmt.Println(“超过1个参数”)
放在
if
语句中,用
/prime.exe 3993 10
运行它,我得到了
超过1个参数0是一个组合,因为它可以被2除,非常感谢!在我添加
n,err:…
之后,我得到了这个错误:
prog.go:36:n声明且未使用
第36行是
n,err:…
如果我删除这一行并使用
n,=…
相反,程序运行正常。因此错误处理有问题。@Nick这是因为
:=
将结果分配给新变量,而您在包含
if
块的外部声明了
n
变量(因此在
if
块内创建的变量不被使用,只使用“外部”变量)。您还可以通过声明
err
(在
if
块的外部或内部)并使用简单赋值来解决此问题:
n,err=…
。我在
n,err=…
之前添加了
var error
,它可以工作。非常感谢你!