TapHome

Typy danych

Typy danych języka skryptowego TapHome: liczby, tekst, typy strukturalne i wyliczeniowe, kolekcje, właściwość .Type, promocja typów w arytmetyce oraz zachowanie Null i NaN.

Typy skalarne

Każda wartość w skrypcie ma konkretny typ. Poniższe nazwy typów są używane w deklaracjach z typem (zobacz Zmienne lokalne), a zwraca je właściwość .Type.

TypWartościUwagi
boolTRUE, FALSEKażda liczba różna od zera jest konwertowana na TRUE, zero na FALSE.
int8, uint8, int16, uint16, int, uint, int64, uint64Liczby całkowite 8-, 16-, 32- i 64-bitoweint i uint to typy 32-bitowe. uint8 to bajt kolekcji bajtów.
float, doubleLiczby zmiennoprzecinkoweLiterały liczbowe i większość arytmetyki dają double.
charJeden znak, 'A'W arytmetyce występuje jako kod znaku.
stringTekst, "abc"+ z tekstem po którejkolwiek stronie łączy tekst.

Int32 x := 4; kończy się błędem Unknown variable or constant 'Int32'. Nazwy takie jak Int32 i UInt32 istnieją tylko wśród typów danych Modbus funkcji MODBUSR i MODBUSW.

Typy strukturalne

Typy strukturalne przechowują kilka wartości dostępnych jako właściwości:

TypPrzechowujeWłaściwości
datetimeDatę i czas z rodzajem (Local, Utc, Unspecified)Zobacz Data i czas
timespanPrzedział czasuDays, Hours, Minutes, Seconds, Milliseconds, TotalDays, TotalHours, TotalMinutes, TotalSeconds, TotalMilliseconds (tylko do odczytu)
httprequestPrzygotowane żądanie HTTP z HTTPREQUESTPath, Method, Body, Headers (odczyt i zapis)
httpresponseOdpowiedź SENDHTTPREQUESTContent, Headers, IsSuccess, StatusCode, ReasonPhrase (tylko do odczytu)
receivedmessagePrzychodzącą wiadomość RECEIVEDMSG skryptu listenerProtocol, Payload, Length, Topic, ContentType, PayloadFormat, ClientId, Expiry, Dup (tylko do odczytu)
blobSurowe bajty, na przykład RECEIVEDMSG.PAYLOADLength (tylko do odczytu)
rgbcolor, hsvcolorKolory, zobacz KoloryRed, Green, Blue oraz Hue, Saturation, Value (odczyt i zapis)
groupvalueWartość grupy urządzeńCalculated, Values (tylko do odczytu)
currentvalueinfo, historyvaluesCzęści zmiennej Info wartościZobacz Info wartości

Typy wyliczeniowe

Typ wyliczeniowy to stały zbiór nazwanych wartości, który niektóre funkcje przyjmują jako parametr:

TypWartościUżywany przez
ModbusRegisterTypeC, H, D, AFunkcje Modbus
ModbusDataTypeInt16, Uint16, Int32, UInt32, Float, Bool, String, Int64, UInt64, Double i ich warianty kolejności bajtów, zobacz Typy danych ModbusFunkcje Modbus, PACKVALUE, UNPACKVALUE
LinearTypeDEFAULT, BOUNDS, STRICT, INFINITELINEAR
DateTimeKindLocal, Utc, UnspecifiedNOW, DATETIME
DayOfWeekMonday … SundayWłaściwości datetime
CompareOptionsNone, IgnoreCase, IgnoreNonSpace, IgnoreSymbols, IgnoreKanaType, IgnoreWidth, OrdinalIgnoreCase, StringSort, OrdinalCOMPARE

Wartość wyliczeniową zapisuje się samą (Utc) albo z typem (DateTimeKind.Utc). Typy wyliczeniowe działają też jako słowa kluczowe deklaracji:

DateTimeKind kind := Utc;
VAR t := NOW(kind);

Kolekcje

collection<T> to lista wartości jednego typu elementu T.

collection<uint16> registers := UINT16COLLECTION(4);
collection<string> names := {"a", "b", "c"};
collection<uint8> data := BYTECOLLECTION("0A0B0C");
LENGTH(names);
# Result: 3
  • Typ elementu wynika z deklaracji, w przeciwnym razie z pierwszego elementu, który nie jest Null. Samo {Null} kończy się błędem Unable to determine collection type.
  • Zagnieżdżone kolekcje nie są obsługiwane: Collection<Collection<>> is not supported.
  • Kolekcje są wartościami referencyjnymi. APPEND, INSERT, REMOVEAT, SETAT i REPLACE zmieniają kolekcję na miejscu i zwracają tę samą kolekcję.
  • BYTECOLLECTION, UINT16COLLECTION i BOOLCOLLECTION tworzą najwyżej 2048 elementów; większą liczbę każda forma zgłasza własnym komunikatem (zobacz Błędy wykonania).
  • LENGTH(c) lub c.Length zwraca liczbę elementów.

Dostępność — kolekcje z typem od Core 2022.2; UINT16COLLECTION i BOOLCOLLECTION od Core 2026.1, kompilacja 39001.

Właściwość .Type

Każda wartość ma właściwość tylko do odczytu .Type, która zwraca nazwę jej typu jako tekst. Dla wartości wyliczeniowej jest to typ wyliczeniowy, na przykład "DateTimeKind".

VAR x := 5.5;
x.Type;
# Result: "Double"
VAR c := BYTECOLLECTION("0A0B");
c.Type;
# Result: "Collection<UInt8>"

Właściwości można odczytać tylko z nazwanej zmiennej. AVG('a', 'c').Type kończy się błędem Unexpected character '.'; najpierw zapisz wartość do zmiennej.

Reguły konwersji typów

W arytmetyce o typie wyniku decyduje pierwsza reguła, która pasuje do obu operandów:

  1. Którykolwiek operand jest double (lub wartością grupy): double.
  2. Którykolwiek operand jest float: float.
  3. Którykolwiek operand jest int64: int64.
  4. Którykolwiek operand jest uint64: uint64.
  5. Którykolwiek operand jest uint: uint, gdy drugi też jest bez znaku, w przeciwnym razie int64.
  6. W pozostałych przypadkach (mniejsze liczby całkowite, bool, char): int.

Dzielenie dwóch liczb całkowitych obcina część ułamkową. Literał liczbowy jest typu double, więc dzielenie przez niego tego nie robi:

int a := 5;
int b := 2;
a / b;
# Result: 2
a / 2;
# Result: 2.5
  • Operatory bitowe działają na liczbach całkowitych; operand double jest najpierw konwertowany na int64.
  • + z tekstem po którejkolwiek stronie łączy tekst: "T=" + 21.5 daje "T=21.5".
  • datetime + liczba dodaje milisekundy, datetime + timespan dodaje przedział, a timespan ± timespan działa zgodnie z oczekiwaniami.
  • Dzielenie przez zero zatrzymuje skrypt komunikatem Division by zero. Zabezpiecz dzielnik funkcją IF.
  • Przypisanie do zmiennej z typem konwertuje wartość na jej typ, zobacz Zmienne lokalne.

Null i NaN

NaN to liczba o nieznanej wartości, na przykład czujnik, który nie został jeszcze odczytany, albo urządzenie w błędzie. Null oznacza, że wartości w ogóle nie ma: usunięte urządzenie albo funkcja, która niczego nie znalazła.

  • Porównanie z literałem NaN (x = NaN, x < NaN) jest odrzucane już przy parsowaniu skryptu: Comparison with NaN is always false. Use the IsNaN method to check for NaN value. Użyj ISNAN.
  • <, >, <= i >= z operandem Null dają FALSE. Null = Null, Null <= Null i Null >= Null dają TRUE, Null = 5 daje FALSE.
  • &, | i ^ z operandem Null dają Null; << i >> dają Null dla wartości Null po lewej stronie, natomiast liczba przesunięć Null zatrzymuje skrypt komunikatem Cannot cast DataType.Null to number.
  • Arytmetyka i logika z Null (Null + 5, !Null) zatrzymuje skrypt komunikatem Operator '+' not defined for 'Null' and 'Double'. Najpierw sprawdź wartość funkcją ISNULL.
  • Warunek IF równy Null liczy się jako FALSE.
  • MIN, MAX, AVG i ORDER pomijają Null i NaN; warianty …STRICT przekazują je dalej. EQUALS(NaN, NaN) daje TRUE.
IF(ISNULL(value) OR ISNAN(value), 0, value);
# Result: the value, or 0 when it is missing or unknown