গো স্ট্রিংকে পূর্ণসংখ্যার টাইপে রূপান্তর করতে চান?


236

আমি একটি স্ট্রিং থেকে প্রত্যাগত রূপান্তর করার চেষ্টা করছি flag.Arg(n)একটি থেকে int। গো-তে এটি করার অলঙ্কৃত উপায় কী?

উত্তর:


298

উদাহরণ স্বরূপ,

package main

import (
    "flag"
    "fmt"
    "os"
    "strconv"
)

func main() {
    flag.Parse()
    s := flag.Arg(0)
    // string to int
    i, err := strconv.Atoi(s)
    if err != nil {
        // handle error
        fmt.Println(err)
        os.Exit(2)
    }
    fmt.Println(s, i)
}

14
func main() { ... }কোনও যুক্তি নেয় না এবং কোনও মূল্য দেয় না। osপ্যাকেজ Exitফাংশনটি ব্যবহার করুন যেমনos.Exit(2).
পিটারএসও

2
বিকল্পভাবে কেবল একটি মারাত্মক উদ্যান করুনpanic(err)
পিটার বেনগটসন

70

সরল স্ট্রিং রূপান্তর করা

strconv.Atoi()ফাংশনটি ব্যবহার করা সবচেয়ে সহজ উপায় ।

মনে রাখবেন যে আরও অনেক উপায় রয়েছে। উদাহরণস্বরূপ fmt.Sscan()এবং strconv.ParseInt()যা আপনাকে বেসটি নির্দিষ্ট করতে পারে এবং উদাহরণস্বরূপ বিটসাইজ করতে পারে তত বেশি নমনীয়তা দেয়। এর ডকুমেন্টেশনে যেমন উল্লেখ করা হয়েছে strconv.Atoi():

এটোই পার্সিয়ান্ট (গুলি, 10, 0) এর সমান, টাইপ ইনটে রূপান্তরিত।

এখানে উল্লিখিত ফাংশনগুলি ব্যবহার করে একটি উদাহরণ দেওয়া হয়েছে (এটি খেলার খেলার মাঠে চেষ্টা করুন ):

flag.Parse()
s := flag.Arg(0)

if i, err := strconv.Atoi(s); err == nil {
    fmt.Printf("i=%d, type: %T\n", i, i)
}

if i, err := strconv.ParseInt(s, 10, 64); err == nil {
    fmt.Printf("i=%d, type: %T\n", i, i)
}

var i int
if _, err := fmt.Sscan(s, &i); err == nil {
    fmt.Printf("i=%d, type: %T\n", i, i)
}

আউটপুট (যুক্তি দিয়ে বলা হয় "123"):

i=123, type: int
i=123, type: int64
i=123, type: int

কাস্টম স্ট্রিং পার্সিং করা হচ্ছে

এমন একটি সহজও রয়েছে fmt.Sscanf()যা বিন্যাসের স্ট্রিংয়ের সাথে আরও বেশি নমনীয়তা দেয় যা আপনি ইনপুটে অতিরিক্ত অতিরিক্ত অক্ষরের পাশাপাশি সংখ্যা বিন্যাস (যেমন প্রস্থ, বেস ইত্যাদি) নির্দিষ্ট করতে পারেন string

এটি একটি সংখ্যা ধারণ করে কাস্টম স্ট্রিং পার্স করার জন্য দুর্দান্ত। উদাহরণস্বরূপ, যদি আপনার ইনপুট এমন কোনও আকারে সরবরাহ করা হয় "id:00123"যেখানে আপনার উপসর্গ রয়েছে "id:"এবং সংখ্যাটি 5 টি সংখ্যক স্থির করা হয়েছে, ছোট হলে শূন্যের সাথে প্যাড করা হবে, এটি খুব সহজেই এখানে বিশ্লেষণযোগ্য:

s := "id:00123"

var i int
if _, err := fmt.Sscanf(s, "id:%5d", &i); err == nil {
    fmt.Println(i) // Outputs 123
}

দ্বিতীয় যুক্তি কী ParseIntনির্দিষ্ট করতে পারে ?
কৌশিক94

1
@ kaushik94 ক্লিক করুন strconv.ParseInt()লিঙ্ক এবং আপনি অবিলম্বে দেখতে পাবেন: ParseInt(s string, base int, bitSize int)। সুতরাং এটির বেসটি: "পার্সিয়ান্ট প্রদত্ত বেসে একটি স্ট্রিংয়ের ব্যাখ্যা করে (2 থেকে 36)"
আইকজা

দ্রষ্টব্য যে বিটসাইজ আর্গুমেন্টটি স্ট্রকনভিতে ars আরও দেখুন: স্ট্যাকওভারফ্লো.com
প্রশ্নগুলি

@ ভিভ হ্যাঁ, এটি সঠিক। ধরনের একটি মান যদি intপ্রয়োজন বোধ করা হয় এবং strconv.ParseInt()ব্যবহার করা হয়, ম্যানুয়াল টাইপ রূপান্তর (থেকে প্রয়োজন হয় int64থেকে int)।
আইজজা

16

দ্রুততম রানটাইম থেকে সবচেয়ে ধীর পর্যন্ত স্ট্রিংগুলি পূর্ণসংখ্যার মধ্যে পার্স করার জন্য এখানে তিনটি উপায়:

  1. strconv.ParseInt(...) দ্রুততম
  2. strconv.Atoi(...) এখনও খুব দ্রুত
  3. fmt.Sscanf(...) মারাত্মক দ্রুত নয় তবে সবচেয়ে নমনীয়

এখানে একটি মানদণ্ড যা প্রতিটি ফাংশনের জন্য ব্যবহার এবং উদাহরণের সময় দেখায়:

package main

import "fmt"
import "strconv"
import "testing"

var num = 123456
var numstr = "123456"

func BenchmarkStrconvParseInt(b *testing.B) {
  num64 := int64(num)
  for i := 0; i < b.N; i++ {
    x, err := strconv.ParseInt(numstr, 10, 64)
    if x != num64 || err != nil {
      b.Error(err)
    }
  }
}

func BenchmarkAtoi(b *testing.B) {
  for i := 0; i < b.N; i++ {
    x, err := strconv.Atoi(numstr)
    if x != num || err != nil {
      b.Error(err)
    }
  }
}

func BenchmarkFmtSscan(b *testing.B) {
  for i := 0; i < b.N; i++ {
    var x int
    n, err := fmt.Sscanf(numstr, "%d", &x)
    if n != 1 || x != num || err != nil {
      b.Error(err)
    }
  }
}

আপনি যত সংরক্ষণ করে তা চালাতে পারেন atoi_test.goএবং চলমান go test -bench=. atoi_test.go

goos: darwin
goarch: amd64
BenchmarkStrconvParseInt-8      100000000           17.1 ns/op
BenchmarkAtoi-8                 100000000           19.4 ns/op
BenchmarkFmtSscan-8               2000000          693   ns/op
PASS
ok      command-line-arguments  5.797s


0

আপনি যদি ইনপুট ডেটা নিয়ন্ত্রণ করেন তবে আপনি মিনি সংস্করণটি ব্যবহার করতে পারেন

package main

import (
    "testing"
    "strconv"
)

func Atoi (s string) int {
    var (
        n uint64
        i int
        v byte
    )   
    for ; i < len(s); i++ {
        d := s[i]
        if '0' <= d && d <= '9' {
            v = d - '0'
        } else if 'a' <= d && d <= 'z' {
            v = d - 'a' + 10
        } else if 'A' <= d && d <= 'Z' {
            v = d - 'A' + 10
        } else {
            n = 0; break        
        }
        n *= uint64(10) 
        n += uint64(v)
    }
    return int(n)
}

func BenchmarkAtoi(b *testing.B) {
    for i := 0; i < b.N; i++ {
        in := Atoi("9999")
        _ = in
    }   
}

func BenchmarkStrconvAtoi(b *testing.B) {
    for i := 0; i < b.N; i++ {
        in, _ := strconv.Atoi("9999")
        _ = in
    }   
}

দ্রুততম বিকল্প (প্রয়োজন হলে আপনার চেকটি লিখুন)। ফলাফল :

Path>go test -bench=. atoi_test.go
goos: windows
goarch: amd64
BenchmarkAtoi-2                 100000000               14.6 ns/op
BenchmarkStrconvAtoi-2          30000000                51.2 ns/op
PASS
ok      path     3.293s

1
কি ? সত্যি? "Go" লিখেছেন এমন লোকেরা অনেক সহজ করে দিয়েছিল। আপনার চাকা স্পিন করবেন না :)
বালাজী বোগগ্রাম রমনারায়ণ

এটোই ("- 9999") সম্পর্কে কী?
ওলেকসী চেচেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.