Comment diviser une chaîne et l'affecter à des variables


151

En Python, il est possible de diviser une chaîne et de l'affecter à des variables:

ip, port = '127.0.0.1:5432'.split(':')

mais dans Go cela ne semble pas fonctionner:

ip, port := strings.Split("127.0.0.1:5432", ":")
// assignment count mismatch: 2 = 1

Question: Comment diviser une chaîne et attribuer des valeurs en une seule étape?


2
splittedString: = strings.Split("127.0.0.1:5432", ":")Ans: = splittedString[index]vous pouvez accéder à la valeur de la chaîne
divisée

Réponses:


249

Deux étapes, par exemple,

package main

import (
    "fmt"
    "strings"
)

func main() {
    s := strings.Split("127.0.0.1:5432", ":")
    ip, port := s[0], s[1]
    fmt.Println(ip, port)
}

Production:

127.0.0.1 5432

Une étape, par exemple,

package main

import (
    "fmt"
    "net"
)

func main() {
    host, port, err := net.SplitHostPort("127.0.0.1:5432")
    fmt.Println(host, port, err)
}

Production:

127.0.0.1 5432 <nil>

Cela divise une chaîne en une liste de chaînes et non en une liste de caractères.
dopatraman

4
Que se passe-t-il si nous obtenons une adresse IPv6?
PumpkinSeed

@PumpkinSeed vient de l'essayer, et je le récupère errmalheureusement de: too many colons in address 2001:0db8:85a3:0000:0000:8a2e:0370:7334:(
JM Janzen

21

Comme il goest flexible, vous pouvez créer votre propre pythonstyle de division ...

package main

import (
    "fmt"
    "strings"
    "errors"
)

type PyString string

func main() {
    var py PyString
    py = "127.0.0.1:5432"
    ip, port , err := py.Split(":")       // Python Style
    fmt.Println(ip, port, err)
}

func (py PyString) Split(str string) ( string, string , error ) {
    s := strings.Split(string(py), str)
    if len(s) < 2 {
        return "" , "", errors.New("Minimum match not found")
    }
    return s[0] , s[1] , nil
}

1
c'est plus qu'un peu différent de l'équivalent python. comment feriez-vous une version à nombre de retours variable?
Groxx

15
J'aime Go mais je n'appellerais pas cela flexible : D
Pijusn

7

Les adresses IPv6 des champs comme RemoteAddrfrom http.Requestsont formatées comme suit: "[:: 1]: 53343"

Fonctionne donc net.SplitHostPorttrès bien:

package main

    import (
        "fmt"
        "net"
    )

    func main() {
        host1, port, err := net.SplitHostPort("127.0.0.1:5432")
        fmt.Println(host1, port, err)

        host2, port, err := net.SplitHostPort("[::1]:2345")
        fmt.Println(host2, port, err)

        host3, port, err := net.SplitHostPort("localhost:1234")
        fmt.Println(host3, port, err)
    }

La sortie est:

127.0.0.1 5432 <nil>
::1 2345 <nil>
localhost 1234 <nil>

2
package main

import (
    "fmt"
    "strings"
)

func main() {
    strs := strings.Split("127.0.0.1:5432", ":")
    ip := strs[0]
    port := strs[1]
    fmt.Println(ip, port)
}

Voici la définition des chaînes.

// Split slices s into all substrings separated by sep and returns a slice of
// the substrings between those separators.
//
// If s does not contain sep and sep is not empty, Split returns a
// slice of length 1 whose only element is s.
//
// If sep is empty, Split splits after each UTF-8 sequence. If both s
// and sep are empty, Split returns an empty slice.
//
// It is equivalent to SplitN with a count of -1.
func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }

voici une erreur "./prog.go:12:17: undefined: str"
Anshu

1

Il existe plusieurs façons de diviser une chaîne:

  1. Si vous voulez le rendre temporaire, divisez-le comme ceci:

_

import net package

host, port, err := net.SplitHostPort("0.0.0.1:8080")
if err != nil {
fmt.Println("Error is splitting : "+err.error());
//do you code here
}
fmt.Println(host, port)
  1. Split basé sur struct:

    • Créez une structure et divisez-la comme ceci

_

type ServerDetail struct {
    Host       string
    Port       string
    err        error
}

ServerDetail = net.SplitHostPort("0.0.0.1:8080") //Specific for Host and Port

Maintenant, utilisez dans votre code comme ServerDetail.HostetServerDetail.Port

Si vous ne voulez pas diviser une chaîne spécifique, procédez comme suit:

type ServerDetail struct {
    Host       string
    Port       string
}

ServerDetail = strings.Split([Your_String], ":") // Common split method

et utilisez comme ServerDetail.Hostet ServerDetail.Port.

C'est tout.


La forme struct ne fonctionne pas:./prog.go:21:4: assignment mismatch: 1 variable but net.SplitHostPort returns 3 values
E. Anderson

1

Ce que vous faites, c'est que vous acceptez une réponse fractionnée en deux variables différentes, et strings.Split () ne renvoie qu'une seule réponse et c'est un tableau de chaînes. vous devez le stocker dans une variable unique, puis vous pouvez extraire la partie de la chaîne en récupérant la valeur d'index d'un tableau.

exemple :

 var hostAndPort string
    hostAndPort = "127.0.0.1:8080"
    sArray := strings.Split(hostAndPort, ":")
    fmt.Println("host : " + sArray[0])
    fmt.Println("port : " + sArray[1])

1

En remarque, vous pouvez inclure les séparateurs lors du fractionnement de la chaîne dans Go. Pour ce faire, utilisez strings.SplitAftercomme dans l'exemple ci-dessous.

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Printf("%q\n", strings.SplitAfter("z,o,r,r,o", ","))
}

0

Golang ne prend pas en charge le décompactage implicite d'une tranche (contrairement à python) et c'est la raison pour laquelle cela ne fonctionnerait pas. Comme les exemples donnés ci-dessus, nous aurions besoin de le contourner.

Une note latérale:

Le déballage implicite se produit pour les fonctions variadiques dans go:

func varParamFunc(params ...int) {

}

varParamFunc(slice1...)

0
**In this function you can able to split the function by golang using array of strings**

func SplitCmdArguments(args []string) map[string]string {
    m := make(map[string]string)
    for _, v := range args {
        strs := strings.Split(v, "=")
        if len(strs) == 2 {
            m[strs[0]] = strs[1]
        } else {
            log.Println("not proper arguments", strs)
        }
    }
    return m
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.