Jak podzielić ciąg i przypisać go do zmiennych

151

W Pythonie możliwe jest podzielenie łańcucha i przypisanie go do zmiennych:

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

ale w Go nie wydaje się działać:

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

Pytanie: Jak podzielić ciąg i przypisać wartości w jednym kroku?

Pyt
źródło
2
splittedString: = strings.Split("127.0.0.1:5432", ":")Ans: = splittedString[index]możesz uzyskać dostęp do wartości podzielonego łańcucha
muthukumar selvaraj Kwietnia

Odpowiedzi:

249

Na przykład dwa kroki

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)
}

Wynik:

127.0.0.1 5432

Na przykład jeden krok

package main

import (
    "fmt"
    "net"
)

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

Wynik:

127.0.0.1 5432 <nil>
peterSO
źródło
To dzieli ciąg na listę ciągów, a nie listę znaków.
dopatraman
4
Co się stanie, jeśli otrzymamy adres IPv6?
PumpkinSeed
@PumpkinSeed właśnie to wypróbowałem i errniestety otrzymałem to z powrotem : too many colons in address 2001:0db8:85a3:0000:0000:8a2e:0370:7334:(
JM Janzen,
21

Ponieważ gojest elastyczny i możesz stworzyć własny pythonpodział stylu ...

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
}
Baba
źródło
1
jest to więcej niż trochę różni się od odpowiednika w Pythonie. jak stworzyłbyś wersję ze zmienną liczbą zwrotów?
Groxx
15
Lubię Go, ale nie nazwałbym tego elastycznym : D
Pijusn
7

Adresy IPv6 dla pól takich jak RemoteAddrod http.Requestmają format „[:: 1]: 53343”

Więc net.SplitHostPortdziała świetnie:

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)
    }

Wynik to:

127.0.0.1 5432 <nil>
::1 2345 <nil>
localhost 1234 <nil>
Glenn McElhoe
źródło
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)
}

Oto definicja ciągów

// 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) }
Prabesh P
źródło
tutaj jest błąd "./prog.go:12:17: undefined: str"
Anshu
1

Istnieje wiele sposobów na podzielenie ciągu:

  1. Jeśli chcesz, aby był tymczasowy, podziel w ten sposób:

_

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. Podziel na podstawie struktury:

    • Utwórz strukturę i podziel w ten sposób

_

type ServerDetail struct {
    Host       string
    Port       string
    err        error
}

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

Teraz użyj w swoim kodzie takich jak ServerDetail.HostiServerDetail.Port

Jeśli nie chcesz dzielić określonego ciągu, zrób to w ten sposób:

type ServerDetail struct {
    Host       string
    Port       string
}

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

i użyj jak ServerDetail.Hosti ServerDetail.Port.

To wszystko.

amku91
źródło
Forma struktury nie działa:./prog.go:21:4: assignment mismatch: 1 variable but net.SplitHostPort returns 3 values
E. Anderson
1

To, co robisz, polega na tym, że akceptujesz podzieloną odpowiedź w dwóch różnych zmiennych, a ciągi znaków.Split () zwraca tylko jedną odpowiedź, a jest to tablica łańcuchów. musisz zapisać go w jednej zmiennej, a następnie możesz wyodrębnić część ciągu, pobierając wartość indeksu tablicy.

przykład:

 var hostAndPort string
    hostAndPort = "127.0.0.1:8080"
    sArray := strings.Split(hostAndPort, ":")
    fmt.Println("host : " + sArray[0])
    fmt.Println("port : " + sArray[1])
Hardik Bohra
źródło
1

Na marginesie, możesz dołączyć separatory podczas dzielenia ciągu w Go. Aby to zrobić, użyj strings.SplitAfterponiższego przykładu.

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Printf("%q\n", strings.SplitAfter("z,o,r,r,o", ","))
}
monkrus
źródło
0

Golang nie obsługuje niejawnego rozpakowywania plasterka (w przeciwieństwie do Pythona) i to jest powód, dla którego to nie zadziała. Podobnie jak w przykładach podanych powyżej, musielibyśmy to obejść.

Jedna uwaga dodatkowa:

Niejawne rozpakowywanie ma miejsce dla funkcji wariadycznych w go:

func varParamFunc(params ...int) {

}

varParamFunc(slice1...)
pr-pal
źródło