English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french

简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE คนไทย Français русский

回答

收藏

Tact 语言基础 |结构(Structs)和消息(Messages)

开源社区 开源社区 7016 人阅读 | 0 人回复 | 2025-03-26

Tact 支持许多专为智能合约使用而定制的 原始数据类型。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。
( K, M3 T2 x# j+ ~  [
: a. Y4 q+ Z# d! e5 k8 t8 r& K- U
. X5 B0 Q7 N1 ~' A; z
' e1 H" I  H  {. b( h" o结构
( |. c8 [3 y, l  G/ e/ v' W结构体可以定义包含多个不同类型字段的复杂数据类型。 它们还可以嵌套。 它们还可以嵌套。! b& g' V6 Z, N* F/ p6 r
  1. struct Point {
    $ E* `& G1 ]/ k5 A4 y' ]
  2.     x: Int as int64;4 E$ x: ^4 ~4 W; ?5 ]$ y
  3.     y: Int as int64;
    / d* S( D/ C2 h: {$ @) S) ?2 ]& `- K0 G
  4. }3 k  b$ X" N) n: D

  5. 6 x+ U# l1 {0 V. Z" ]9 e
  6. struct Line {3 l! v0 T* \9 Q3 @
  7.     start: Point;0 v$ x3 w! l, o# Q) h: i
  8.     end: Point;
    & G. N' }) v. f& R/ T
  9. }
复制代码
结构体还可以包含默认字段,并定义可选类型的字段。 结构体还可以包含默认字段和定义[可选类型]字段(/book/optionals)。 如果您有很多字段,但又不想一直在 new instances 中为它们指定通用值,那么这将非常有用。
. H; e2 \, s$ W; r2 T
  1. struct Params {! K+ F( e9 N0 o" ?) z
  2.     name: String = "Satoshi"; // default value
    * w! D- N( S+ x
  3. $ V- M  e# v3 R7 g9 A
  4.     age: Int?; // field with an optional type Int?
    " n* `4 Q" {3 @4 ^8 x+ S4 ^
  5.                // and default value of null
    3 r$ K  [$ a% F& a: ^

  6. ' {! x" p1 ?" Q8 R7 O  ~- F  P
  7.     point: Point; // nested Structs
    7 @( m( R1 s: r6 [0 a% H5 @& \$ \
  8. }
复制代码
字段的顺序很重要,因为它与TL-B 模式 中的内存布局一致。 不过,与某些采用手动内存管理的语言不同,Tact 在字段之间没有任何填充。
" T7 M+ y# K) S$ @% J4 ~. r; G9 @
$ r: t% L! V4 p4 G
  j8 R1 {2 K4 L) N1 I% i/ g% B9 x. y* M3 b5 S8 \5 X
消息$ {3 }( s3 y) d# E: H4 N0 N) g
消息中可以包含 结构体:
7 d& T& b0 J3 Z5 ^* d
  1. struct Point {# f/ l# Y4 d5 o2 c7 [
  2.     x: Int;$ I! M) _1 k- C! J2 R3 B
  3.     y: Int;
    7 }! n& }1 G1 Z$ X
  4. }$ u& K0 M* Q' s
  5. 5 ^8 c+ d. i4 g
  6. message Add {1 c- M3 c0 i9 R& g
  7.     point: Point; // holds a struct Point
    6 e2 G8 f. P" I% q* U7 H4 w
  8. }
复制代码
  1. // This Message overwrites its unique id with 0x7362d09c0 u3 @$ T4 k+ I5 u1 h
  2. message(0x7362d09c) TokenNotification {# y6 ^: K, B' L
  3.     forwardPayload: Slice as remaining;( H# u+ b4 f" }/ t6 o( Q" B
  4. }
复制代码
这对于要处理特定智能合约的某些操作码(如 Jetton standard)的情况非常有用。 该合约能够处理的操作码简表为此处以 FunC 表示。 它们是智能合约的接口。/ @  Q5 c# O* O3 }3 Z$ A

9 Y4 ^, D, g: E6 d6 q, b2 R& P7 t1 F& y
8 c9 X2 m9 Z0 P( _: G操作! u/ @# L. U. x: |9 g
实例化
& h/ O! t7 J, i) e, h) J, B$ }$ |( h创建 Struct 和 Message 实例类似于 function calls,但需要用大括号 {}(大括号)代替小括号 ()指定参数:
5 u5 w* N$ a9 S+ X% k2 i- e* V
  1. struct StA {3 I; _, k  l2 l  Y8 [1 ~
  2.     field1: Int;
    ( x3 a- X- d0 r5 n6 g8 v* h# k
  3.     field2: Int;
    + k' `; Z* ]* f. s1 V" {
  4. }, o6 Y. P" q3 V4 N2 M  q  B: Y

  5. + n; O" C6 F$ o6 R
  6. message MsgB {
    9 [' a8 D/ |* a: U
  7.     field1: String;* r. T2 ?: J8 Y, b- N
  8.     field2: String;) ~4 l7 [/ u4 \% n8 U6 C$ E1 ^3 F
  9. }
    ; |8 C* _- C6 y

  10. - y  K$ I! b. I& l) ~, f/ l
  11. fun example() {' X2 Q" x# A) u  _
  12.     // Instance of a Struct StA
    ' E& Q& B  p8 M. w. t
  13.     StA{
    & a8 ?. g. m, l7 {% E# T9 A8 E
  14.         field1: 42,
    / l' G; G% t1 _6 x9 I* D
  15.         field2: 68 + 1, // trailing comma is allowed8 Z7 d" Q- C5 `4 ?# U
  16.     };
    ' k' ^4 b9 d- z3 ?' I: G* g
  17. + U: I9 I" h+ I% M1 R
  18.     // Instance of a Message MsgB& W" w% K7 l- S
  19.     MsgB{
    . p4 M: g' C* n0 o8 l0 A
  20.         field1: "May the 4th",
    * N  P; |' b( }' W- K, W
  21.         field2: "be with you!", // trailing comma is allowed
    7 R* }2 B0 J* m- R3 Y
  22.     };
    3 v" r( g& K+ i* d6 |* m- A
  23. }
复制代码
  1. struct PopQuiz {
    , `4 X! l7 T! y; p1 Y# U0 w
  2.     vogonsCount: Int;2 X; U4 I7 X% N9 T2 U5 N
  3.     nicestNumber: Int;! W: A- b  q/ O1 D4 c
  4. }
    ! z7 ?1 V4 g. F$ `) b

  5. / g7 y# b; ~; y# n
  6. fun example() {
    # E' ~5 E# ?& T  j
  7.     // Let's introduce a couple of variables
    ' c4 v+ N. S1 W  w" ]# Q# V
  8.     let vogonsCount: Int = 42;
    - a" x! Y# u3 p, Q+ z- R$ i# M% ]  U
  9.     let nicestNumber: Int = 68 + 1;
    0 Q2 \  s, p! N1 T

  10. 8 Y* i+ P1 _# N8 }; A
  11.     // You may instantiate the Struct as usual and assign variables to fields,
    3 D" S$ W8 @! p3 T# h; M* r; a6 q' G$ b
  12.     // but that is a bit repetitive and tedious at times
    " L: L0 c  q9 h) G8 z, L* m3 E
  13.     PopQuiz{ vogonsCount: vogonsCount, nicestNumber: nicestNumber };7 ~, q/ K( H1 Y  M4 U9 r6 j% }/ A

  14. + U) i2 H) `3 f7 [! I% I+ @9 V
  15.     // Let's use field punning and type less,' ?. Z1 ?$ @. |* _. v
  16.     // because our variable names happen to be the same as field names/ ^3 x2 a+ t1 [, j3 q9 X# j; Y- u3 @( v
  17.     PopQuiz{
    ' O7 v# Y- p0 g! k7 a
  18.         vogonsCount,: T+ j2 q+ p& f8 J+ p& r1 h) v
  19.         nicestNumber, // trailing comma is allowed here too!
    % ]: ?! i( A7 H8 W, O! I0 `0 b
  20.     };9 i/ f; W7 @# l$ Z. R+ W) @, y0 N; V+ B
  21. }
复制代码
  1. struct Big {0 m( F( _3 F3 H
  2.     f1: Int;  l7 t# Y  v! y( y
  3.     f2: Int;
    ) x9 Y' I1 f. O: x, v* C
  4.     f3: Int;3 ?1 l4 g0 ^; K7 X. h9 ^& f* Q5 A6 j
  5.     f4: Int;
    ! l) @' m- w  Y  E, B' @
  6.     f5: Int;, g( c6 B- d3 p- P2 N) k! W
  7.     f6: Int;9 f& ?: C7 L; R  |' Z
  8. }$ \) A, {4 O% R  l# L
  9. $ L) n- Z( J) u: C
  10. fun conversionFun() {2 A* ]9 e3 l) J7 ?: @; ?$ Y
  11.     dump(Big{
    " \- Q( n6 _$ V9 X
  12.         f1: 10000000000, f2: 10000000000, f3: 10000000000,6 u  v: q: n) g1 u1 p7 \  R4 {2 K
  13.         f4: 10000000000, f5: 10000000000, f6: 10000000000,
    # {: Y5 J& N5 M* \
  14.     }.toCell()); // x{...cell with references...}
    : X& }0 l% ^- N9 K  H0 O
  15. }
复制代码
  1. struct Fizz { foo: Int }) k5 n! Z, N( ^* f- j/ B
  2. message(100) Buzz { bar: Int }0 f) {& m& f) A. I
  3. 8 u& P0 E( F# t$ m% s- k- z# A
  4. fun constructThenParse() {1 `5 L* |- j! y. a
  5.     let fizzCell = Fizz{foo: 42}.toCell();
    2 g9 k2 d1 I! `) a
  6.     let buzzCell = Buzz{bar: 27}.toCell();9 [3 J5 p" L/ U$ }+ V/ J) Y

  7. + `$ M7 C$ O5 l$ @( Y1 b, X
  8.     let parsedFizz: Fizz = Fizz.fromCell(fizzCell);/ b9 o7 H; o. c5 Q/ `
  9.     let parsedBuzz: Buzz = Buzz.fromCell(buzzCell);* c) K6 R( [* L' i0 w
  10. }
复制代码
  1. struct ArbitraryStruct {}0 o3 T. C" o  N, C' _
  2. message(0x2A) ArbitraryMessage {}$ w% s2 f9 {" w6 V3 K

  3. + _. q, G. ]% r) a7 y7 y
  4. fun lawOne() {4 N5 x& R0 @4 \" ~2 o
  5.     let structInst = ArbitraryStruct{};/ n/ i0 R% Y& g; D! f
  6.     let messageInst = ArbitraryMessage{};  r" ?/ |& ^, {, C
  7. 5 P4 |: G- s+ D( @6 ?( d% A
  8.     ArbitraryStruct.fromCell(structInst.toCell());   // = structInst
    : {4 v- I; ^9 ^+ J% M1 ~
  9.     ArbitraryMessage.fromCell(messageInst.toCell()); // = messageInst
    + v" c) E2 x$ z& u, h( J
  10.   l/ Q) f/ c0 S+ C
  11.     // Same goes for Slices, with .toCell().asSlice() and .fromSlice()
    : u, C: T0 r/ j8 V; [# y' b. ^* H7 q
  12. 6 \0 P0 @" W  o# {/ p9 a  b* x
  13.     ArbitraryStruct.fromSlice(structInst.toCell().asSlice());   // = structInst  g4 r8 K; ?1 l: H& F/ u2 j8 S: X& y6 a
  14.     ArbitraryMessage.fromSlice(messageInst.toCell().asSlice()); // = messageInst
    # k3 L1 ~1 I  G, Z
  15. }
复制代码
对于任何与给定 Struct/Message 具有相同 TL-B 布局的 cell,调用 Struct.fromCell()(或 Message.fromCell()),然后通过 .toCell() 将结果转换为 Cell,就会得到原始 cell 的副本:
  1. struct ArbitraryStruct { val: Int as uint32 }
    6 Z) m/ l3 y8 U
  2. message(0x2A) ArbitraryMessage {}7 q( U' L/ L: Y

  3. / [: S# i6 }" g# s) O. o
  4. fun lawTwo() {
    - H, e, r9 f. i9 c
  5.     // Using 32 bits to store 42 just so this cellInst can be
    8 [- ?8 K% H; J  Z# P
  6.     // re-used for working with both ArbitraryStruct and ArbitraryMessage6 f3 x- o2 z3 k6 t
  7.     let cellInst = beginCell().storeUint(42, 32).endCell();0 l( h8 i7 m6 @. F! H/ m

  8. # P$ u5 R, l0 Z4 H* G
  9.     ArbitraryStruct.fromCell(cellInst).toCell();  // = cellInst* m2 d3 B: I6 l
  10.     ArbitraryMessage.fromCell(cellInst).toCell(); // = cellInst' M% l% {2 x) P) x" m' x- V. E

  11. - R4 _4 d' {' G7 C  i( n
  12.     // Same goes for Slices, with .fromSlice() and .toCell().asSlice()
    + O' R/ [8 W1 K+ H7 e5 l
  13.     let sliceInst = cellInst.asSlice();
    & l% Q6 N4 p6 i: P
  14. . t! A* B4 B2 J  J
  15.     ArbitraryStruct.fromSlice(sliceInst).toCell().asSlice();  // = sliceInst
    ) b, F% s* t  D8 y! V
  16.     ArbitraryMessage.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst
    # V; m8 ?- m) F6 _% C) L- m! N6 Y
  17. }
复制代码

7 X) Q0 U& ]) v+ }, M  Y
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则