In Go, I want to find the last element in an array of integers.
I have a list:
[0.0.1, 0.0.2, 0.0.3]
I just want:
0.0.3
Every time I try to return the last element the console returns
%!(EXTRA uint8=10)
Which I assume means I need to convert a byte array to a slice?
Here's my code:
cmd := exec.Command("git", "tag")
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("cmd.Run() failed with %s
", err)
}
fmt.Printf("Variable Type:
%s
", reflect.TypeOf(out))
fmt.Printf("Variable:
%s
", (out))
slice := out[0: len(out)]
releaseVersion := slice[len(slice) - 1]
fmt.Printf("release version:", releaseVersion)
Here's the output:
Variable Type:
[]uint8
Variable:
0.0.1
0.0.2
0.0.3
release version:%!(EXTRA uint8=10)
The reason you see: %!(EXTRA uint8=10)
is you are calling Printf
without a format option. You should just call fmt.Println
instead.
10
is the encoding of the newline character.
Now, the meat of your question:
You have a byte array (slice).
You are trying to interpret it as lines (strings separated by ' ').
Interpreting a byte array as a string is easy (assuming the bytes do in fact represent a utf-8 string):
// assume buf is []byte
var text = string(buf)
You want to treat this as a list of strings. Since git tag
returns lines, you can split by ' ' or you can just call strings.Fields
which splits by generic whitespace (including newlines); documented here: https://golang.org/pkg/strings/#Fields
var parts = strings.Fields(text)
Now you can easily just get the last element:
parts[len(parts)-1]
But for safety you should check the list has some elements, otherwise you will crash on out-of-bounds access.
cmd := exec.Command("git", "tag")
bufOut, err := cmd.Output()
if err != nil {
log.Fatalf("cmd.Run() failed with %s
", err)
}
textOut := string(bufOut)
parts := strings.Fields(textOut)
if len(parts) == 0 {
log.Fatal("No tags")
}
releaseVersion := parts[len(parts)-1]
fmt.Println("release version:", releaseVersion)
WHY DOES THIS GOT TO BE SO COMPLEX? IN JAVASCRIPT I CAN JUST DO pop()
It's not really that complex. This is just how computers work. When a program runs, it has a standard output which is essentially a byte stream.
I'm guessing javascript does this step for you automatically:
textOut := string(bufOut)
parts := strings.Fields(textOut)
i.e. converting the program output to a list of strings separated by new lines.
The combined output of the git tag
command is a list of tags
separated by a new line. When you execute the cmd.CombinedOutput()
it returns this value but as a []byte
. Now, I believe that what you actually want is a list of strings. So, what you can do is convert the out
byte array into a string, and then split it by using the
strings.Split()
function. Then you can access the last tag
by its index.
package main
import (
"fmt"
"reflect"
"strings"
)
func main() {
cmd: = exec.Command("git", "tag")
out, err: = cmd.CombinedOutput()
if err != nil {
log.Fatalf("cmd.Run() failed with %s
", err)
}
fmt.Printf("Variable Type:
%s
", reflect.TypeOf(out))
fmt.Printf("Variable:
%s
", (out))
outString := string(out)
outStringArray := strings.Split(outString, "
")
fmt.Printf("Last tag is: %s", outStringArray[len(outStringArray) - 1])
}
You should see Last tag is: 0.0.3
printed in the console in your example.
I hope it helps.