问题
While trying to solve the question How to print a sqlite table content with genie programming language I found out that I could try to call PrintSingleRecipe as a callback from Database.exec. However, it seems that a callback cannot be a regular function, they have some property that I do not seem to find over in the internets.
I am calling it in this way:
else if response is "3" //Show a Recipe
res:string = UserInterface.raw_input("Select a recipe -> ")
sql:string = "SELECT * FROM Recipes WHERE pkID = %res"
db.exec(sql, PrintSingleRecipe, null)
And the function itself looks like:
def PrintSingleRecipe(n_columns:int, values:array of string, column_names:array of string)
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
for i:int = 0 to n_columns
stdout.printf ("%s = %s\n", column_names[i], values[i])
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "Ingredient list"
print " "
stdout.printf("%-5s", "%03i" )
However, I get the following error at compilation:
valac --pkg sqlite3 --pkg gee-0.8 cookbook.gs
cookbook.gs:42.26-42.42: error: Argument 2: Cannot convert from `PrintSingleRecipe' to `Sqlite.Callback?'
db.exec(sql, PrintSingleRecipe, null)
^^^^^^^^^^^^^^^^^
Compilation failed: 1 error(s), 0 warning(s)
How to properly run the callback in Genie?
回答1:
The Vala compiler does type checking on a function when a function is passed as a parameter. When a function is used in this way it is called a "delegate". Specifically the Vala compiler will check that the function's signature matches the signature of the delegate type definition. A function's signature is made up of its parameter types and return type. Cannot convert from 'PrintSingleRecipe' to 'Sqlite.Callback?'
means the PrintSingleRecipe
function's signature doesn't match the Sqlite.Callback
delegate definition's signature.
The Sqlite.Callback delegate definition is shown here:
http://valadoc.org/#!api=sqlite3/Sqlite.Callback
You have rightly identified the parameters required are int, array of string, array of string
, but you also need to include the return type. In this case it is an int
. So your callback should look like:
def PrintSingleRecipe(n_columns:int,
values:array of string,
column_names:array of string
):int
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
for i:int = 0 to n_columns
stdout.printf ("%s = %s\n", column_names[i], values[i])
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "Ingredient list"
print " "
stdout.printf("%-5s", "%03i" )
return 0
Returning non-zero will abort the query. See https://www.sqlite.org/capi3ref.html#sqlite3_exec
来源:https://stackoverflow.com/questions/34099538/how-to-use-sqlite-callback-in-genie