Myślałem, że QML obsługuje funkcje lambda ze względu na obsługę anonimowych funkcji JavaScript oraz fakt, że funkcje są obiektami pierwszej klasy, ale nie działają tak, jak się spodziewałem. Wziąć ten kod:QML: Funkcja Lambda działa nieoczekiwanie
Item {
property var items: []
function handler(item) {
console.log(item);
}
Component.onCompleted: {
for (var i = 0; i < 3; ++i) {
var item = someObj.createObject();
item.someValueChanged.connect(function() {
handler(item); });
items.push(item);
console.log("Adding:", item);
}
}
Component {
id: someObj
Item {
property bool someValue: false
Timer {
running: true
onTriggered: {
parent.someValue = true;
}
}
}
}
}
Próbuję użyć lambda function() { handler(item); }
tak, że gdy sygnał jest emitowany someObj::someValueChanged
element emitujący jest przekazywany do funkcji handler(item)
.
I zakłada, że każda pętla by utworzyć nową instancję lambda, a odniesienie item
wiązałoby się odniesienie do przykładu someObj
utworzonego w pętli (tj item
byłyby wychwytywane przez lambda). Ale to nie wydaje się być w przypadku, gdy wyjście jest:
qml: Adding: QQuickItem_QML_1(0x2442aa0)
qml: Adding: QQuickItem_QML_1(0x2443c00)
qml: Adding: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
Jak widać, zarówno cała funkcja jest zastępowana na każdej pętli lub tylko odniesienie item
, tak że ostatecznie tylko ostatni stworzył someObj
jest określona. Czy ktoś może mi wyjaśnić, dlaczego lambdy (jeśli to nawet to, co jest) nie działają tak, jak się spodziewam? A czy to jest problem z QML, czy ogólny kod JavaScript?
Ach, to ma sens (w każdym razie dla JS). Dziękuję Ci! – cmannett85
@ cmannett85 - co by się stało w C++, jeśli spróbujesz uruchomić opóźnioną lambdę, odwołując się do locals funkcji, która wykracza poza zakres? Najlepszy przypadek, jeśli na początku był na stosie, a stos nie poszedł na tę głębokość, a pamięć nie została nadpisana, może działać, ale najprawdopodobniej ulegnie awarii. – dtech
Prawda, z wyjątkiem tego, że w C++ można określić, co jest przechwytywane _i jak_. Coś, czego JS nie obsługuje (przynajmniej wersja używana przez QtQuick). – cmannett85