I am quite new to the v language and i discovered this feature, however it seems like i am doing something wrong.
I have a struct that gathers information in case an error is found somewhere and i'd like to create a function in the same structure to return a string containing all the values so that i can call it and store it in a variable the proper way: error_msg := error.to_string()
I am using v version 0.3.3
Having the Error struct:
pub struct Error {
pub:
text string
row int
col int
complementary string
}
I have tried:
- Creating a function and return it that way(This works but its not what i'd like)
fn to_string(e Error) string {
return e.text+'\n in row '+ e.row+' at col '+ e.col+'\n'+e.complementary
}
- Appending a method to the struct(Not working)
fn (e Error) to_string() string {
return e.text+'\n in row '+ e.row+' at col '+ e.col+'\n'+e.complementary
}
I would like the second option to work but it is outputing the following error while compiling it:
structs/error.v:11:7: error: cannot define new methods on non-local type Error
9 | }
10 |
11 | fn (e Error) to_string() string {
| ~~~~~
12 | return e.text+'\n in row '+ e.row+' at col '+ e.col+'\n'+e.complementary
13 | }
The function and the struct are in the same module as expected and even in the same file Full code
module structs
pub struct Error {
pub:
text string
row int
col int
complementary string
}
fn (e Error) to_string() string {
return e.text+'\n in row '+ e.row+' at col '+ e.col+'\n'+e.complementary
}
That being said, it is going to be called in another file and module:
pub fn read(file_name string) (int, string) {
data := read_file(file_name) or {
error_str := Error{text: 'File "$file_name" does not exist', row: 2, col: 0}
return 1, error_str.to_string()
}
return 0, data
}
The error
cannot define new methods on non-local type Erroroccurs becauseErroris a V builtin, thus already defined (non-locally), and you cannot add a new method to that here.Also, you're getting this error on the method definition because it presumably precedes the struct's definition in your source code. If you flipped their order of definition (struct first, then the method), the issue wouldn't change but the error message would have been more to the point, reading:
cannot register struct `Error`, another type with this name exists.The quick fix
Give your
structa new name:A more idiomatic approach
Define proper custom error types which you can then use as actual errors: Either manually implement the
IErrorinterface (requiring the two methodsmsg() stringandcode() int), or just embed the interface's default implementationError(yes, the one you have accidentally been trying to shadow) which provides empty copies of both methods, so you only have to add what's needed. For instance: