2016-07-25 6 views
2

Zuerst bin ich ein Anfänger in C/C++, sei gnädig.Wie dynamische Variablen implementiert für Node.JS in C++

In Node.JS sind alle Variablen dynamisch und wir können die Variable jeden beliebigen Typ übergeben. Also, Node.JS write mit C++ und in C++ oder C gibt es keine dynamischen Variablen. Also, wie dynamische Variablen implementiert?

In JS:

var A; 
A = 5; //Integer 
A = "Hello world!"; //String 
A = 2.5; //Float 
A = 5 * "Hello world!"; // I do not sure about this one. 
+1

Oh, C++ 11 hat dynamisch typisierte Variablen; Sie werden vom Compiler oder der Standardlaufzeit nicht für Sie bereinigt. Sie können versuchen, eine mit "union" gepaart mit RTTI Flags zu erstellen (zB: 'std :: type_info'). Beachten Sie, dass es in C++ 17 ein standardisiertes "std :: any" gibt, das ein Objekt ist, das sicher von jedem Typ sein kann. – KABoissonneault

+1

Werfen Sie einen Blick auf [std :: any] (http://en.cppreference.com/w/cpp/utility/any) und [std :: variant] (http://en.cppreference.com/w/ cpp/Dienstprogramm/Variante). Nicht genau das Gleiche, aber ähnlich. Sie sind möglicherweise noch nicht in jedem System implementiert, da sie Teil von C++ 17 sein sollen. –

+0

Ich denke, diese Frage ist zu weit gefasst. Vielleicht könnten Sie es besser machen, indem Sie sich auf einige Aspekte dynamischer Variablen oder auf einen bestimmten Teil des JS-Codes konzentrieren? – svick

Antwort

2

Es gibt zwei gute Ansätze.

Die erste besteht darin, lokale Variablen als einen Namen für eine Folge von Werten zu behandeln. Auf diese Weise können Sie mit den Werten arbeiten, nicht mit den Variablen, und die Werte haben Typen, selbst wenn Variablen dies nicht tun.

Ein weniger effizienter Weg, um damit umzugehen, ist die Schaffung von polymorphem Speicher, wie boost::any oder std::any. Im Fall von JS gibt es nur wenige Basistypen, also ist boost::variant oder std::variant mehr als genug. (Komplexe JS-Objekte sind nur aufgeprägte Schlüsselwertkarten).

Eine variant ist eine Art von markierten Union. Die Datenstruktur hat eine Ganzzahl oder eine Enumeration, die angibt, um welchen Typ sich der Speicher handelt, und dann einen Speicherblock, der wie jeder dieser Typen behandelt werden kann. Accessoren prüfen den Typ und interagieren dann mit den Daten, als ob es dieser Typ wäre.

Die markierte Union kann die gespeicherten Daten durch Daten eines anderen Typs ersetzen, indem Sie sie manuell zerstören (unter Verwendung der Syntax .~X()), und dann manuell einen neuen Typ an dieser Stelle erstellen (unter Verwendung der Plazierung new Syntax). Dies in C zu tun ist im Grunde das Gleiche mit etwas weniger Sprachunterstützung.

Die erste Technik - herauszufinden, welcher Typ wirklich da ist und damit arbeitet - tendiert dazu, eine Größenordnung schneller zu sein (in den Fällen, in denen ich es profiliert habe), so dass intelligente Skript-Engines wirklich hart arbeiten um das zu ermöglichen. Aber das zweite ist funktional genug.

Jetzt weiß ich nicht, ob node.js tatsächlich zu C/C++ - Code rekompiliert wird. Aber nach den Schichten des Kompilierens und Parsens und Bytecodes wird es von einem C/C++ - oder Assembly-Interpreter interpretiert, oder es wird selbst zum Maschinencode kompiliert, ohne einen C/C++ - Zwischenschritt zu durchlaufen. Die Lösung für dieses Problem im Maschinencode entspricht in jedem Fall der C/C++.