检查 string 是否为 int

如何在 Go 中检查字符串值是否为整数?

差不多

v := "4"
if isInt(v) {
fmt.Println("We have an int, we can safely cast this with strconv")
}

注意: 我知道 strconv.Atoi返回一个错误,但是有没有其他函数可以做到这一点?

strconv.Atoi的问题在于它将返回 7作为 "a7"

114711 次浏览

As you said, you can use strconv.Atoi for this.

if _, err := strconv.Atoi(v); err == nil {
fmt.Printf("%q looks like a number.\n", v)
}

You could use scanner.Scanner (from text/scanner) in mode ScanInts, or use a regexp to validate the string, but Atoi is the right tool for the job.

this is better, you can check for ints upto 64 ( or less ) bits

strconv.Atoi only supports 32 bits

if _, err := strconv.ParseInt(v,10,64); err == nil {
fmt.Printf("%q looks like a number.\n", v)
}

try it out with v := "12345678900123456789"

You can use unicode.IsDigit():

import "unicode"


func isInt(s string) bool {
for _, c := range s {
if !unicode.IsDigit(c) {
return false
}
}
return true
}

You can use govalidator.

Code

govalidator.IsInt("123")  // true


Full Example

package main


import (
"fmt"
valid "github.com/asaskevich/govalidator"
)


func main() {
fmt.Println("Is it a Integer? ", valid.IsInt("978"))
}

Output:

$ go run intcheck.go
Is it a Integer?  true

this might help

func IsInt(s string) bool {
l := len(s)
if strings.HasPrefix(s, "-") {
l = l - 1
s = s[1:]
}


reg := fmt.Sprintf("\\d{%d}", l)


rs, err := regexp.MatchString(reg, s)


if err != nil {
return false
}


return rs
}

You might also use regexp to check this.

It can be a little overkill, but it also gives you more flexibility if you want to extend your rules.

Here some code example:

package main


import (
"regexp"
)


var digitCheck = regexp.MustCompile(`^[0-9]+$`)


func main() {
digitCheck.MatchString("1212")
}

If you want to see it running: https://play.golang.org/p/6JmzgUGYN3u

Hope it helps ;)

This manually checks each CHAR to see if it falls between 0 and 9.

func IsDigitsOnly(s string) bool {
for _, c := range s {
if c < '0' || c > '9' {
return false
}
}
return true
}

Most of the above posted solutions are neat and nice.

Below is a simple solution without using any library:

func IsNumericOnly(str string) bool {


if len(str) == 0 {
return false
}


for _, s := range str {
if s < '0' || s > '9' {
return false
}
}
return true
}

Test cases

func TestIsNumericOnly(t *testing.T) {
cases := []struct {
name      string
str       string
isNumeric bool
}{
{
name:      "numeric string",
str:       "0123456789",
isNumeric: true,
},
{
name:      "not numeric string",
str:       "#0123456789",
isNumeric: false,
},
}


for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
assert.Equal(t, c.isNumeric, IsNumericOnly(c.str))
})
}
}

you can check if all runes are between 0 and 9

isNotDigit := func(c rune) bool { return c < '0' || c > '9' }
b := strings.IndexFunc(s, isNotDigit) == -1

be careful if your strings input could be in any length.

in cases where you have to check for monster strings length the strconv approach is useless. it will produce an ErrRange error.

for such scenarios:

s := strings.TrimSpace(val)


r := regexp.MustCompile(`^\d+$`)


isNum := r.Match([]byte(s))