Go Error: continue is not in a loop - go

I have written go code which has a for loop, code is given below. but when i build the code i get 'continue is not within loop'. i can't understand why this is happening. Kindly help
Go Version:
go version go1.7.5 linux/amd64
Complete Code at the below link
https://pastebin.com/0ZypMYVK
reference Screenshot
for k:=0;k < len(args);k++{
fmt.Println("k is ", k)
hsCode := args[k]
lenChk:=checkHashLen(hsCode)
if lenChk==false {
fmt.Println("Length should be 32" )
continue
}
codeBytes,_ := json.Marshal(hsCode)
APIstub.PutState(strconv.FormatInt(makeTimestamp(),10), codeBytes)
fmt.Println("Added: ", k)
}
Error
./hashcode.go:88: continue is not in a loop

Your problem is here:
//push single code on the block
func (s *SmartContract) pushCode(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
hsCode := args[0]
lenChk := checkHashLen(hsCode)
if lenChk == false {
fmt.Println("Length should be 32")
continue
}
codeBytes, _ := json.Marshal(hsCode)
APIstub.PutState(strconv.FormatInt(makeTimestamp(), 10), codeBytes)
return shim.Success(nil)
}
The error explains what is going wrong. You're using the keyword continue when not in a for loop, this function doesn't contain a for loop.
initCodeLedger contains a for loop, so you are getting distracted by that, but that's not the line no given in the error which is around line 86/87/88. Ideally post code on play.golang.org if asking a question like this.

Related

How can I scan a rune?

So far, I haven't been able to print a rune by scanning it with fmt.Scan and printing it with fmt.Print. This is the vary basic code I'm working on:
package main
import "fmt"
func main() {
var c rune
fmt.Scan(&c)
fmt.Printf("%c", c)
}
But it doesn't work, in fact, Printf doesn't produce any output. Instead, by manually assigning a char to my variable c (like var c rune = 'a', without using fmt.Scan), I'm able to print the wanted rune. How can I scan a rune?
As we know Scan return n and err so please check for error under Scan statement as follows
n, err := fmt.Scan(&c)
if err != nil {
fmt.Println(err)
}
It will clearly show you the error and why it was ignored.
Other than the above, please try it locally on your own laptop instead of the playground because on the playground it most of the time gives an EOF error as most of them do not support reading from the terminal.
I hope the above helps you in debugging the issue.
Other Reference:
Scanf ignores if not provided \n

How can I log the value of passed parameters to a function?

My aim is to create a logging function that lists the name of a function and the list of passed parameters.
An example would be the following:
func MyFunc(a string, b int){
... some code ...
if err != nil{
errorDescription := myLoggingFunction(err)
fmt.Println(errorDescription)
}
}
func main(){
MyFunc("hello", 42)
}
// where MyLoggingFunction should return something like:
// "MyFunc: a = hello, b = 42, receivedError = "dummy error description"
So far it seems that in Go there is no way to get the name of the parameters of a function at runtime, as answered in this question, but I could give up this feature.
I've managed to get the function name and the memory address of the passed parameters by analysing the stack trace, but I'm hitting a wall when it comes to print somehow the parameters starting from their address (I understand that it might not be trivial depending on the type of the parameters, but even something very simple will do for now)
This is an implementation of the logging function I'm building (you can test it on this playground), is there away to print the parameter values?
func MyLoggingFunction(err error) string {
callersPCs := make([]uintptr, 10)
n := runtime.Callers(2, callersPCs) //skip first 2 entries, (Callers, GetStackTrace)
callersPCs = callersPCs[:n]
b := make([]byte, 1000)
runtime.Stack(b, false)
stackString := string(b)
frames := runtime.CallersFrames(callersPCs)
frame, _ := frames.Next()
trimmedString := strings.Split(strings.Split(stackString, "(")[2], ")")[0]
trimmedString = strings.Replace(trimmedString, " ", "", -1)
parametersPointers := strings.Split(trimmedString, ",")
return fmt.Sprintf("Name: %s \nParameters: %s \nReceived Error: %s", frame.Function, parametersPointers, err.Error())
}
If there are other ideas for building such logging function without analysing the stack trace, except the one that consists in passing a map[string]interface{} containing all the passed parameter names as keys and their values as values (that is my current implementation and is tedious since I'd like to log errors very often), I'd be glad to read them.

How to check if user input is empty with bufio?

I'm new with Go syntax, just trying to pass an error if the user did not input anything...
[EDIT] I would like the following function to stop running if the user did not input anything, and print a log. My if required && answer == "" statement doesn't seem to work as "You must enter a value." does not log when the user does not input anything.
func QAR(q string, r string, required bool) string {
reader := bufio.NewReader(os.Stdin)
// Print the question
fmt.Printf(q)
answer, _ := reader.ReadString('\n')
// If the answer is empty, return a log
if required && answer == "" {
log.Fatal("You must enter a value.")
// Can I just use return to block it?
return
}
// Print the response with the answer
if r != "" {
fmt.Println(r, answer)
}
return answer
}
The typical pattern in go is to return multiple values, the last of which is an error, if one occurred. So your function signature could look like this:
func QAR(q string, r string, required bool) (string, error)
And the return statements like this:
return "", fmt.Errorf("user provided no input")
// ...
return answer, nil
[EDIT]
Note that bufio.Reader.ReadString(...) includes the delimiter, so you probably need to check if answer == "\n".

Go error handling, what's the idiomatic way for making things DRY

Consider the following example program which is primitive stack implementation in Go:
package main
import "fmt"
import "errors"
const MAX_SIZE = 10
var a [10]int
var top int = -1
func main() {
printStack()
push(1)
printStack()
push(23)
printStack()
pop()
push(2)
push(24)
push(56)
push(87)
push(97)
push(47)
push(37)
push(31)
push(69)
printStack()
push(75)
println("Top element is", getTop())
}
func push(x int) (int, error) {
if top >= (MAX_SIZE - 1) {
return 0, errors.New("Error: Prevented Stackoverflow. Stack full")
}
top += 1
a[top] = x
return 0, nil
}
func pop() {
top -= 1
}
func getTop() int {
return a[top]
}
func printStack() {
fmt.Println(top+1, "Stack: ", a, "Top", top)
}
Now, I read Error handling and Go & it seems the above way of returning multiple values is the way to handle errors in go.
But what I don't understand is that does do gophers check of errors on every statement? Coming from other languages this concept it bit hard for me to grok. So the question is
What is the idiomatic way of handling errors in above problem?
Is considered a bad practice if I don't check for errors? if yes, then I am supposed to check the output of push() everytime I call it?
Basically what I want to know if how would a experienced gopher do error handling in the above program?
Play URL: https://play.golang.org/p/_AnZLvY-28
[Update]
Added a real-world program where I fetch data from database & output to json. http://play.golang.org/p/dDApCYprjU
Yes, the idiomatic way to produce errors is to return multiple values. The idiomatic way to handle errors is this:
val, err := myFunc()
if err != nil {
// do something with err
}
// do something with val
At the end of the day it's a judgement call, but it's almost always good practice to handle errors. The code you're writing is also a bit unusual, you normally don't have 10 calls to the same function back-to-back, so the verbose error handling you'd have to do is more a result of the original code. For instance, you could use a loop:
for _, num := range []int{2, 24, 56, 87, 97, 47, 37, 31, 69} {
_, err := push(num)
if err != nil {
panic(err)
}
}
You have some other things that are more problematic than not handling the push errors though. One minor thing is there is no reason for push to always return 0, why not only have it return an error, instead of an int and an error? The bigger problem is that pop keeps decrementing top, and getTop just accesses a[top], so you can easily get a runtime panic if top becomes negative from having popped too much. You probably want some error handling or other safeguards in your pop and getTop functions.
This is a standard way of handling the errors in go-lang. There are two options that can follow after an error took place.
1.log the error and entirely quit the program
log the error and do some relevant task
Option one example :
func funcX() {
rtnval, err := funcY()
if err != nil {
fmt.Println("error: ", err)
os.Exit(1)
}
//rtnval
}

unexpected semicolon or newline before else even though there is neither before else if

I'm trying to fix these errors in my golang code and if someone could help me with that, I'd appreciate it.
Here is my code: http://play.golang.org/p/yELWfIdWz5
Although, the one that is troubling me the most is the first one on line 21 where the error says: syntax error: unexpected semicolon or newline before else. I can't find a semicolon or new line on or just before line 21 at all.
Also, what do the errors on line 28 and 32 mean ( non-declaration statement outside function body )-- those statements are in the main() function and the last closing brace closes that function so why is there an error there.
I have a feeling that all of these errors are due to the first one.
I'd greatly appreciate any and all help in resolving these or at least learning more about them.
Here is the code:
package main
import "fmt"
func main() {
var current_mid = ""
current_topic := make(map[string][]string)
f, err := os.Open(*inputFile)
if err != nil {
fmt.Println(err)
return
}
r := bufio.NewReader(f)
xmlFile, _ := os.Create("freebase.xml")
line, err := r.ReadString('\n')
for err == nil{
subject, predicate, object := parseTriple(line)
if subject == current_mid{
current_topic[predicate] = append(current_topic[predicate], object)
}
else if len(current_mid) > 0{
processTopic(current_mid, current_topic, xmlFile)
current_topic = make(map[string][]string)
}
current_mid = subject
line, err = r.ReadString('\n')
}
processTopic(current_mid, current_topic, xmlFile)
if err != io.EOF {
fmt.Println(err)
return
}
}
You need to put the 'else' on the line with the close brace in Go.
Go inserts a ; at the end of lines ending in certain tokens including }; see the spec. That means that, fortunately, it can insert the ending semicolon on x := func(){...} or x := []int{1,2,3}, but it also means it inserts one after the } closing your if block. Since if {...} else {...} is a single compound statement, you can't stick a semicolon in the middle of it after the first }, hence the requirement to put } else { on one line
It's unusual, but it keeps the semicolon-insertion behavior simple. Having been hit with unexpected program behavior because of the cleverer semicolon insertion rules in another semicolon-optional language, this seems alright in the scheme of things.
And I can see how the error message was confusing, but 'newline before else' just refers to the newline after the } on the previous line.
https://golang.org/doc/effective_go.html#if
You can find the explanation here, but I find it to be a bit bikeshedding. For example, this, unintuitive as it is, compiles:
if your_age >= 16 {
say("\n You can earn a Drivers License."); } else
if your_age >= 18 { say("\n You can vote."); } else
{ say("\n You can have fun."); }

Resources