confusion with compiletime $for iter var scoping #25505
Replies: 6 comments
-
The V docs, when talking about closures inheriting variables from the scope they're in, say It also says This behavior has nothing to do with whether or not the closure is inside a comptime scope - the rules still apply, regardless. |
Beta Was this translation helpful? Give feedback.
-
ok, I still dont realy understand why that also applies to comptime vars but I probably misunderstand what comptime fors do. sorry for pressing this so much, I just really want to understand. anyways, I tried to capture ...
on_text_changed: fn [field] (_ &gui.InputCfg, s string, mut w gui.Window) {
mut state := w.state[App]()
state.search.$(field.name) = s
println("${field.name}")
println(state.search)
}
... and the result confused me even more. If I type 'x' into a field of
so apperently for the what is happening? |
Beta Was this translation helpful? Give feedback.
-
I don't know how to register a function to update a variable by calling struct Str {
f int = 1
s string
}
fn set_strings[T](mut t T, value string) {
$if T is $struct {
$for field in T.fields {
$if field is string {
t.$(field.name) = value
}
}
}
}
fn main() {
mut s := Str{}
assert s.s == ''
set_strings(mut s, 'default')
assert s.s == 'default'
} Seems to me you need to register apart in another generic function your |
Beta Was this translation helpful? Give feedback.
-
yes, but I know that all my fields are strings. I think I didnt realy communicate what my problem/confusion is that well, So struct SearchPart {
mut:
part string
manufacturer string
movement string
} And I thought this code (bit shortened from my real code to focus on essential point): $for field in SearchPart.fields {
search_inputs << gui.text(text: "${field.name}:")
search_inputs << gui.input(
text: app.search.$(field.name)
on_text_changed: fn (_ &gui.InputCfg, s string, mut w gui.Window) {
mut state := w.state[App]()
state.search.$(field.name) = s
}
)
} would let the compiler transform this into: search_inputs << gui.text(text: "part:")
search_inputs << gui.input(
text: app.search.part
on_text_changed: fn (_ &gui.InputCfg, s string, mut w gui.Window) {
mut state := w.state[App]()
state.search.part = s
}
)
search_inputs << gui.text(text: "manufacturer:")
search_inputs << gui.input(
text: app.search.manufacturer
on_text_changed: fn (_ &gui.InputCfg, s string, mut w gui.Window) {
mut state := w.state[App]()
state.search.manufacturer = s
}
)
search_inputs << gui.text(text: "movement:")
search_inputs << gui.input(
text: app.search.movement
on_text_changed: fn (_ &gui.InputCfg, s string, mut w gui.Window) {
mut state := w.state[App]()
state.search.movement = s
}
) completly unrolled and hardcoded into the result, so no need to capture and no need to loop through the fields inside the closure. btw. I tested to write the unrolled version by hand, so I know there isnt another logic bug in the code. |
Beta Was this translation helpful? Give feedback.
-
Just and idea, next code is pseudocode. Replace your struct elements by a map and pass to your gui functions the references to read the keys and write the values of the map: type Search = map[string]string
fn new_search(fields ...string) Search {
mut m := map[string]string
for f in fields {
m[f] = ''
}
return Search(m)
}
fn (mut search Search) register(mut inputs []gui.Input) {
for k, _ in search {
inputs << gui.text(text: '${k}:')
inputs << gui.input(
text: '${k}'
on_text_changed: fn[mut search, k](_ &gui.InputCfg, s string, mut w gui.Window) {
search[k] = s
}
)
}
}
fn main() {
search := new_search('part', 'manufacturer', 'movement')
search.register(inputs)
} This does not need compile time and I think the |
Beta Was this translation helpful? Give feedback.
-
I dont realy want to use a map for something that has a fixed comptime known set of fields, that just feels wrong. Well I have a solution to mitigate my problem now, but I dont realy like it (because its not the way how the $for field in SearchPart.fields {
field_rt := &app.search.$(field.name)
search_inputs << gui.text(text: "${field.name}:")
search_inputs << gui.input(
text: app.search.$(field.name)
on_text_changed: fn [field_rt] (_ &gui.InputCfg, s string, mut w gui.Window) {
unsafe {
*field_rt = s
}
}
)
} I also did look at some generated c code of some small test code, and I think I understand whats happening now. PS: sorry for kinda ignoring your anwers and basicaly having a monologue about my findings. I just wasnt realy searching for a workaround but for an answer for why the code I wrote doesnt do what I think it should do anyways Ill close the thread now |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi all,
Im completly new to V, just found it yesterday. Im currently writing my first V program.
And I have a little question about comptime for + type introspection.
So I want to generate some code for every field of a struct. I tried this:
but I get this error:
so I suspect the problem is that
on_text_changed
closure needs to capturefield
.But why? As far as I understand it
field
is a comptime var and gets baked info the resulting unrolled for loop. So why shouldfield
need to be captured by the closure?what am I missing?
thanks in advance,
chol
Beta Was this translation helpful? Give feedback.
All reactions