Neuer Syntax in Version 3.3.10.0

    • Offizieller Beitrag

    Hallo,

    Es hat ja mittlerweile schon Tradition, dass es zu Weihnachten meistens eine neue AutoIt stable gibt. So auch dieses Jahr, und diesmal hat sich einiges geändert! Hier ist ein kleines Beispiel, wie sich der Syntax geändert hat - falls ihr Fragen habt, immer her damit, ich hoffe es hilft dem Ein oder Anderen weiter :)

    Spoiler anzeigen
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Example()

    [/autoit] [autoit][/autoit] [autoit]

    Func Example()
    Local $tStruct, $sTest, $vMsgB, $vTestFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;Automatische größe von Arrays, wenn [] benutzt wird (danke an minx)
    Local $aTestArray[] = [1, 2, 3, 4]

    [/autoit] [autoit][/autoit] [autoit]

    ;Hier gab es gleich zwei Probleme: Zum einen konnte kein leeres Array erstellt werden. ([0])
    ;Zum anderen konnten statische Arrays nicht mit ReDim erhöht werden - das funktioniert nun beides!
    Static $aEmptyArrayOnStatic[0]

    [/autoit] [autoit][/autoit] [autoit]

    ;Vergrößere das Array
    ReDim $aEmptyArrayOnStatic[4]

    [/autoit] [autoit][/autoit] [autoit]

    $aEmptyArrayOnStatic[0] = "Testbla"
    $aEmptyArrayOnStatic[1] = "Test"
    $aEmptyArrayOnStatic[2] = "Test1"
    $aEmptyArrayOnStatic[3] = "Test2"

    [/autoit] [autoit][/autoit] [autoit]

    ;Neuer Array Display Dialog. Wähle paar Elemente aus, klick auf "Run User Func" und schau was passiert :)
    _ArrayDisplay($aEmptyArrayOnStatic, "Item auswählen + auf User Func klicken", "", 0, Default, Default, Default, 0xff9999, "_UserArrayFunc")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $vMsgB = MsgBox;Setze Variable vMsgB auf die Funktion MsgBox
    ;Hier beschwert sich zwar der Wrapper, funktioniert aber trotzdem. (Ohne Wrapper ausführen)
    $vTestFunc = _TestFunc123;und die Variable auf die Funktion _TestFunc123
    $tStruct = DllStructCreate("char bla[1024]; int x[4]");tStruct auf eine Struktur

    [/autoit] [autoit][/autoit] [autoit]

    ;Setzte den datatype bla auf "Hallo Welt"
    $tStruct.bla = "Hallo Welt"

    [/autoit] [autoit][/autoit] [autoit]

    ;Das funktioniert nicht, da tStruct.bla eine konstante ist
    ;~ _TestFunc123($tStruct.bla)

    [/autoit] [autoit][/autoit] [autoit]

    ;Da muss man erstmal sTest den wert von tStruct.bla zuweisen
    $sTest = $tStruct.bla
    ;und dann (jetzt neu) mit Call aufrufen, ByRef ging früher mit Call nicht
    Call($vTestFunc, $sTest)
    ;Oder aber auch so:
    ;~ $vTestFunc($sTest)

    [/autoit] [autoit][/autoit] [autoit]

    ;Hier geben wir das nun in einer MessageBox aus (die wir ja oben deklariert haben)
    $vMsgB(0, "", "tStruct: " & $tStruct.bla & @CRLF & "sTest: " & $sTest)

    [/autoit] [autoit][/autoit] [autoit]

    ;Hier schauen wir noch mal mit tenären operator (wie in C++) nach, ob sTest nicht tStruct.bla enstpricht

    [/autoit] [autoit][/autoit] [autoit]

    $vMsgB(0, "", ($sTest = $tStruct.bla ? "Ups, da ist was falsch gelaufen" : "Jipp, genau so solls sein, sTest != tStruct.bla"))

    [/autoit] [autoit][/autoit] [autoit]

    ;Hier noch mal FuncName und IsFunc ausprobieren
    $vMsgB(0, "", "vTestFunc entspricht der Funktion " & FuncName($vTestFunc) & " und es ist eine " & (IsFunc($vTestFunc) = 2 ? "native Funktion" : "User defined Funktion"))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Auch interessat, nun kann man direkt hinter Funktionen die ein Array zurück geben, das spezifische Element auswählen
    $vMsgB(0, "", "Erstes Element: " & StringSplit("Hallo,Welt,Komma,Seperator", ",")[1] & @CRLF & "Erstes Element von UserFunc: " & $vTestFunc($sTest)[1])

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Hardcoded funktioniert der Zugriff auf Subindexe
    $tStruct.x(1) = 11
    $tStruct.x(2) = 22
    $tStruct.x(3) = 33
    $tStruct.x(4) = 44

    [/autoit] [autoit][/autoit] [autoit]

    $vMsgB(0, "", "Sollte 33 sein: " & $tStruct.x(3))

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 4
    ;~ $tStruct.x($i) = $i; Das funktioniert nicht, fehler vom Compiler, wird wohl noch ausgebessert. Stattdessen z.B. die untere Zeile verwenden
    $tStruct.x(($i)) = $aTestArray[$i - 1]; Mit doppelter klammer funktioniert es. Dannk an Mars

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    $vMsgB(0, "", "Sollte " & $aTestArray[2] & " sein: " & $tStruct.x(3))
    EndFunc ;==>Example

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _UserArrayFunc($aArray, $aSelected)
    #forceref $aArray
    MsgBox(0, "", "Du hast " & $aSelected[0] & " Item(s) selected!")
    EndFunc ;==>_UserArrayFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _TestFunc123(ByRef $sTest)
    Local $avTest[] = [5, 4, 3, 2, 1]
    $sTest = "Test 2"
    Return $avTest
    EndFunc ;==>_TestFunc123

    [/autoit]

    Gruß,
    Spider

    Edit: Subindex bei Struktur und automatische Array größe hinzugefügt (dank an minx)
    Edit2: Paar kleine Updates

  • Hier ist eine Lösung für das Struct-Problem, das immer noch existiert ($ muss ergänzt werden): [ offen ] Struct via "Struct.Element" ansprechen - Beta 3.3.9.5

    Hier ein komplettes Beispiel des Struct-Zugriffs und des tenären Operators: AutoIt Versions-Archiv 3.3.8.1 bis 3.3.10.0 (Stable am 23.12.13) und Benchmarks für 3.3.8.1 bis 3.3.9.13

    Zumal:

    [autoit]

    Local $Array[0] ; Leerer Array
    Local $Array2[] = [1,2,3,4] ; automatische Größe

    [/autoit]
    • Offizieller Beitrag

    Da man Funktionen jetzt Variablen zuweisen kann, ist auch eine Funktion hinzugekommen, mit der man auf native oder User definierte Funktion der Variablen prüfen kann:

    [autoit]

    ; == Neue Prüffunktion

    [/autoit][autoit][/autoit][autoit]

    Func _AnyFunc()
    Return True
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    $UserFunc = _AnyFunc
    $NativeFunc = ConsoleWrite

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite('User Funktion: ' & IsFunc($UserFunc) & @LF) ; 1 = User Funktion
    ConsoleWrite('Native Funktion: ' & IsFunc($NativeFunc) & @LF) ; 2 = Native Funktion

    [/autoit]

    Funktionen in Variablen ermöglichen nun auch die Verwendung von Funktionen als Parameter anderer Funktionen:

    [autoit]

    ; == Funktion als Parameter

    [/autoit][autoit][/autoit][autoit]

    Func _ParameterFunktion($a, $b)
    Return $a + $b
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    Func _Any($x, $param)
    Return $x + $param($x+1, $x+2)
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    $paramF = _ParameterFunktion

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite( _Any(10, $paramF) & @LF) ; ==> 33

    [/autoit]

    Der direkte Zugriff auf Elemente von Funktionen, die ein Array zurückgeben ist nicht nur bei integrierten, sondern auch bei selbst erstellten Funktionen möglich:

    [autoit]

    ConsoleWrite(_ArrayRet()[2] & @LF) ; ==> "C"

    [/autoit][autoit][/autoit][autoit]

    Func _ArrayRet()
    Local $aRet[] = ['A','B','C','D','E']
    Return $aRet
    EndFunc

    [/autoit]
  • Das Problem mit dem Index in Structs kann auch ohne Eval sehr einfach gelöst werden.

    [autoit]

    For $i = 1 To 4
    ;~ $tStruct.x($i) = $i; Das funktioniert nicht, fehler vom Compiler, wird wohl noch ausgebessert. Stattdessen z.B. die untere Zeile verwenden
    $tStruct.x(($i)) = $i; Mit Klammern funktioniert es
    Next

    [/autoit]

    Durch die Klammern wird $i in einen Ausdruck dessen Ergebnis $i ist umgewandelt. Und mit Ausdrücken hat der Index kein Problem ;)

    lg
    M

  • Was auch ganz interessant ist:

    [autoit]

    ConsoleWrite(obj(100).x & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Func obj($var)
    Local $tStruct = DllStructCreate('int x')
    $tStruct.x = $var
    Return $tStruct
    EndFunc

    [/autoit]
  • Das Problem mit dem Index in Structs kann auch ohne Eval sehr einfach gelöst werden.

    [autoit]

    For $i = 1 To 4
    ;~ $tStruct.x($i) = $i; Das funktioniert nicht, fehler vom Compiler, wird wohl noch ausgebessert. Stattdessen z.B. die untere Zeile verwenden
    $tStruct.x(($i)) = $i; Mit Klammern funktioniert es
    Next

    [/autoit]

    Durch die Klammern wird $i in einen Ausdruck dessen Ergebnis $i ist umgewandelt. Und mit Ausdrücken hat der Index kein Problem ;)

    lg
    M


    Yeah! :rock::party::thumbup:

  • Sehr schöne änderungen, danke für den Einblick, kann man sicherlich clever einbauen, ähnelt schon etwas der OOP meiner Meinung.
    :thumbup:

    Sind TV-Quizfragen zu einfach? A) Ja B) Harry Potter

    Spoiler anzeigen

    Ich gebe zu dieser Post hat wahrscheinlich nicht viel geholfen,
    aber ich versuche wenigstens zu helfen :rolleyes:

    • Offizieller Beitrag

    Eines fällt mir gerade beim Thema Structures auf. Die Umsetzung mit der neuen Syntax ist hier leider nicht konsistent.
    Bsp.:

    [autoit]


    ; == Strukturen können Bezeichner führen, diese müssen aber aus Buchstaben bestehen
    $tStruct = DllStructCreate("int links;int rechts")
    ; mit neuer Syntax ansprechbar:
    $tStruct.links = 120
    $tStruct.rechts = 70

    [/autoit][autoit][/autoit][autoit]

    ; == Wenn die Felder der Struktur jedoch keine Bezeichner führen, kann die neue Syntax nicht angewendet werden
    ; == Hier wäre eigentlich folgendes sinnvoll und wünschenswert:
    $tStruct = DllStructCreate("int;int")
    ; mit neuer Syntax ansprechen über Nummer des Elements:
    $tStruct.1 = 120
    $tStruct.2 = 70

    [/autoit]
  • Was leider immernoch nicht geht ist Return [1, 2, 3]

    [autoit]

    Func GetArray($a, $b, $c)
    Local $x[] = [$a, $b, $c]
    Return $x
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    Func GetArray2($a, $b, $c) ; Geht nicht
    Return [$a, $b, $c]
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    Func MyFunc($a, $b, $c)
    Return GetArray($a, $b, $c)
    EndFunc

    [/autoit]

    Kann man selbstnatürlich per Hilfsfunktion ohne weiteres lösen.
    lg
    M

  • Anders als in den (meisten) anderen Sprachen werden Funktionsaufrufe von rechts nach links ausgewertet. Man muss die Klammern selber setzen:

    [autoit]


    Func foo()
    Return MsgBox
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    foo()(0, "", "Hello, world!") ; gibt einen fehler

    [/autoit][autoit][/autoit][autoit]

    (foo())(0, "", "Hello, world!") ; so muss es sein

    [/autoit]