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

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

回答

收藏

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

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

Tact 支持许多专为智能合约使用而定制的 原始数据类型。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。
7 N: b( U, t( m* p
. p1 ~  |+ v6 ~( p9 r
( l* K9 z) `" ~% e7 A' k# h
" o7 S# z* D3 `6 u" Q" Y+ l结构
# Y) u* @+ {+ t结构体可以定义包含多个不同类型字段的复杂数据类型。 它们还可以嵌套。 它们还可以嵌套。
/ n& e+ y3 s! [# `  Q
  1. struct Point {
    1 D. V0 U% p1 D& v2 o
  2.     x: Int as int64;- h( f6 W6 T3 _& V
  3.     y: Int as int64;
    7 y1 d- v/ {  }4 j+ K9 @
  4. }
    7 e& F% x# ?  t6 ?1 l# G

  5. * n1 t- _! O8 K6 c( g( Z
  6. struct Line {
    9 j+ y  ^7 s& w9 o. B  `3 |
  7.     start: Point;
    6 a# ~) B; n) k% A* [; Z
  8.     end: Point;
    " h0 |! ~5 ]4 Q
  9. }
复制代码
结构体还可以包含默认字段,并定义可选类型的字段。 结构体还可以包含默认字段和定义[可选类型]字段(/book/optionals)。 如果您有很多字段,但又不想一直在 new instances 中为它们指定通用值,那么这将非常有用。
8 H- e' F* m1 Z9 Q" r3 z; w
  1. struct Params {
      p8 c4 m$ Z. r; v7 ?9 C3 J
  2.     name: String = "Satoshi"; // default value# k: _: d8 u8 b' |# z: d
  3. + T1 K: K1 w: q" d/ }9 K
  4.     age: Int?; // field with an optional type Int?
    ; C6 t' Y6 w% x8 P0 D# V
  5.                // and default value of null
    / e. k+ T6 C6 F6 p( i/ R- H) Y/ C

  6. 5 N4 b2 Y2 n: a
  7.     point: Point; // nested Structs
    3 p7 ^4 ~/ t0 _# Z; ^; d; K
  8. }
复制代码
字段的顺序很重要,因为它与TL-B 模式 中的内存布局一致。 不过,与某些采用手动内存管理的语言不同,Tact 在字段之间没有任何填充。
2 `, P/ k+ g1 w' N9 {; _
+ }2 m2 d2 L6 a- ]/ f- h, _3 F, I
& m. b9 Q4 T$ k
消息1 D' a6 N& }' Q, j; ?% {
消息中可以包含 结构体:
1 j3 }! O: C# L4 Y0 ?
  1. struct Point {- K- E+ e( i* `
  2.     x: Int;
    + l' A$ y0 ]  K9 R6 P
  3.     y: Int;! T7 i; E  d8 h
  4. }: ^. K% J0 F) ^" m6 g
  5. * d( O9 @0 \' p0 Z$ R
  6. message Add {8 _2 o- @6 k0 ?6 A1 d
  7.     point: Point; // holds a struct Point1 z+ i+ I* X0 k) Z
  8. }
复制代码
  1. // This Message overwrites its unique id with 0x7362d09c+ [, Z0 `- j9 r& \/ [+ o9 z
  2. message(0x7362d09c) TokenNotification {7 e# Z" v6 |! J$ A6 B% \4 b! f) m& L
  3.     forwardPayload: Slice as remaining;
    * C9 M8 `7 }# ?
  4. }
复制代码
这对于要处理特定智能合约的某些操作码(如 Jetton standard)的情况非常有用。 该合约能够处理的操作码简表为此处以 FunC 表示。 它们是智能合约的接口。% E( O' U0 B; }5 U0 a

4 ]' {. N* e0 M1 F
% V- N: k2 s+ t- I4 ?操作- R% K! W2 r/ t7 M# H2 f" f" @6 b
实例化, Q" A( g: h) @4 \/ o
创建 Struct 和 Message 实例类似于 function calls,但需要用大括号 {}(大括号)代替小括号 ()指定参数:
% K; U+ h8 z( k1 g3 f, q
  1. struct StA {
    : Z5 k; E: J) p" ?; b; f) \
  2.     field1: Int;# F; m) K: `' a% g5 N
  3.     field2: Int;
    3 Y; s2 m0 T% r, T/ P4 d
  4. }" n4 T7 ^3 V* q- J+ q

  5. ) ~" I6 u$ y- W+ \! g: P
  6. message MsgB {$ I8 f, d* N  H4 ]
  7.     field1: String;
    # O+ ]" ?7 u1 f) L
  8.     field2: String;
    $ s' J7 a: D* N" c6 x6 q
  9. }
    8 V  S0 h8 \- W, p3 i  U+ k  b* u! \
  10. / w1 Z4 }3 I  `( X, d9 e
  11. fun example() {
    0 Z% \9 G7 e5 |
  12.     // Instance of a Struct StA
    3 O# w9 T: H  i- B
  13.     StA{
    ( m/ Y2 k; v1 Q" D% _6 B1 k! `% K
  14.         field1: 42,4 @) b/ {! z0 B7 }3 N8 o9 [0 {
  15.         field2: 68 + 1, // trailing comma is allowed
    2 `- `. S! g+ {8 t  p: [
  16.     };: o1 C$ R; t6 O3 N
  17. & H3 F5 L$ H5 K' d+ g% N8 t
  18.     // Instance of a Message MsgB
    # i5 {2 o: W; ?* a- {. }/ n% }
  19.     MsgB{
    8 l* f/ y7 E9 A* H5 O
  20.         field1: "May the 4th"," f- Z  j/ t2 M4 s, r. B# w
  21.         field2: "be with you!", // trailing comma is allowed, l: u* e' T* g+ D% r2 i8 A8 R, s
  22.     };
    : g# a7 z+ w% \2 ^9 X
  23. }
复制代码
  1. struct PopQuiz {9 n$ W1 O* t, B8 y3 @, D/ X
  2.     vogonsCount: Int;9 v2 ?* {) R0 `7 ]$ i4 Z' J) H
  3.     nicestNumber: Int;  P/ R) Y; n( A5 w9 X% ?
  4. }
    % l/ A1 m# Y9 W
  5. $ u( ]- H+ d9 E; m+ `3 m* B5 H6 z
  6. fun example() {  z; }& b+ E  e6 \$ u$ }, G
  7.     // Let's introduce a couple of variables
    : H5 E" D+ h0 }) q
  8.     let vogonsCount: Int = 42;6 V/ s/ n! b- C9 Z2 f+ B
  9.     let nicestNumber: Int = 68 + 1;
    . f. _+ V2 p/ i2 @

  10. ' D6 A8 G7 w3 \' Q8 S6 e. [
  11.     // You may instantiate the Struct as usual and assign variables to fields,
    8 ~4 s9 S" `% U+ f
  12.     // but that is a bit repetitive and tedious at times9 [8 a" i8 Y4 f, l7 y5 M
  13.     PopQuiz{ vogonsCount: vogonsCount, nicestNumber: nicestNumber };
    $ U, b. i4 _: U5 w; l

  14. 5 [8 h- s: n0 l6 S) ^& K& Q
  15.     // Let's use field punning and type less,. t6 A) u) Y4 s* R; j# I
  16.     // because our variable names happen to be the same as field names+ i9 N) {' F* c" K% j" B. M7 ?
  17.     PopQuiz{
      h' h7 V, @) ?
  18.         vogonsCount,
    8 T' @, U6 v' O
  19.         nicestNumber, // trailing comma is allowed here too!/ ]+ ?) J3 K; A1 j* k$ s$ H$ [  [6 ?
  20.     };
    ( p1 u. s+ s/ a* G
  21. }
复制代码
  1. struct Big {
    6 o1 i9 m8 P) r5 e( j
  2.     f1: Int;
    1 y# M' Q( r- a+ B7 [4 K5 M7 H
  3.     f2: Int;4 T  c6 M2 n. a2 v* V
  4.     f3: Int;
    5 y$ j/ S0 V1 u6 H- f: V% P
  5.     f4: Int;
    9 m5 r3 i. Y3 h" h  L8 q3 w  o% r
  6.     f5: Int;
    + P7 e/ f; X: C& x( X% t
  7.     f6: Int;; W) S( j% P8 i7 F  {4 \
  8. }
    1 N" z# |5 }/ r$ r( w: M9 j9 u+ |: _
  9. % g6 S- f: U9 e/ r9 W: ^
  10. fun conversionFun() {- J9 k) f2 r' K+ Y) e0 M
  11.     dump(Big{
    7 }9 O7 U! i" \% v4 S  Z
  12.         f1: 10000000000, f2: 10000000000, f3: 10000000000,0 |# E3 P* `- l
  13.         f4: 10000000000, f5: 10000000000, f6: 10000000000,  W! c4 J5 J# F# P; w% \7 D
  14.     }.toCell()); // x{...cell with references...}
    - d% N9 I$ f$ `0 z
  15. }
复制代码
  1. struct Fizz { foo: Int }
    8 Q) S$ ~; ~* w4 l( h- g
  2. message(100) Buzz { bar: Int }  ?0 W' {, g& {" I; g+ I+ o7 G
  3. 7 V: H% |( C# E. {% t, d; B% z
  4. fun constructThenParse() {+ H1 {) ], J2 m$ D& }
  5.     let fizzCell = Fizz{foo: 42}.toCell();
    ( y& V/ Y# Q9 O+ ]
  6.     let buzzCell = Buzz{bar: 27}.toCell();
    5 [7 K2 N* v, v! V" a

  7. / r6 n* |' V7 E/ I
  8.     let parsedFizz: Fizz = Fizz.fromCell(fizzCell);. E$ [, w9 O- O1 F1 C4 y
  9.     let parsedBuzz: Buzz = Buzz.fromCell(buzzCell);. h( g( G1 D1 c4 X
  10. }
复制代码
  1. struct ArbitraryStruct {}  G3 ]6 f9 t. `" S$ E
  2. message(0x2A) ArbitraryMessage {}: w' i( G% [' [/ Y

  3. ) B, [! p2 l, x  x) E0 m( ~
  4. fun lawOne() {; @2 k6 k3 Z' X4 C% r' N% j
  5.     let structInst = ArbitraryStruct{};) P: E# x) Q7 I' k/ c  ]: g
  6.     let messageInst = ArbitraryMessage{};& v: K9 P( L" w! o/ r

  7. , D0 l: g. X; W
  8.     ArbitraryStruct.fromCell(structInst.toCell());   // = structInst
    2 y- U- P3 S2 M# Z' i0 S
  9.     ArbitraryMessage.fromCell(messageInst.toCell()); // = messageInst
    ! R+ _6 e6 x. ^' [
  10. 6 M! L$ o; V+ _# w
  11.     // Same goes for Slices, with .toCell().asSlice() and .fromSlice()
    * [" x+ \1 P$ l, ]: \# p# E) p

  12. 1 p6 B8 C5 u$ R
  13.     ArbitraryStruct.fromSlice(structInst.toCell().asSlice());   // = structInst; q' I: q3 j& u
  14.     ArbitraryMessage.fromSlice(messageInst.toCell().asSlice()); // = messageInst  I: u. ]/ s1 Y
  15. }
复制代码
对于任何与给定 Struct/Message 具有相同 TL-B 布局的 cell,调用 Struct.fromCell()(或 Message.fromCell()),然后通过 .toCell() 将结果转换为 Cell,就会得到原始 cell 的副本:
  1. struct ArbitraryStruct { val: Int as uint32 }* N; u- l( _- D  X2 A. J
  2. message(0x2A) ArbitraryMessage {}
    # i) o, C( |- x* s
  3. * X* C2 C  p4 {8 P
  4. fun lawTwo() {1 p; K4 D+ i3 D% l1 a+ ~
  5.     // Using 32 bits to store 42 just so this cellInst can be
    # {- o7 A; [! x8 k* o. T4 p
  6.     // re-used for working with both ArbitraryStruct and ArbitraryMessage
    : r7 [6 l/ N* l1 s+ d% k7 }7 s8 C
  7.     let cellInst = beginCell().storeUint(42, 32).endCell();
    . ], R4 `9 _/ |1 d

  8. 8 {; _; N& w+ g7 L
  9.     ArbitraryStruct.fromCell(cellInst).toCell();  // = cellInst
    & Y! Q0 c6 f, Z" h
  10.     ArbitraryMessage.fromCell(cellInst).toCell(); // = cellInst0 r1 _5 x6 `  a6 S

  11. ! l- V. Z4 A, y0 ]# d' ]9 O
  12.     // Same goes for Slices, with .fromSlice() and .toCell().asSlice()
    4 Y4 `6 b; |  ^) u6 u% K0 W; m6 B9 v
  13.     let sliceInst = cellInst.asSlice();
    1 E0 X8 J% u6 p7 j

  14. 0 x4 F: T/ W, r. @
  15.     ArbitraryStruct.fromSlice(sliceInst).toCell().asSlice();  // = sliceInst9 r# N# o* o' v2 `
  16.     ArbitraryMessage.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst0 h9 Q1 r& E1 h* }2 ]- q
  17. }
复制代码
) K" v  I9 o  E: _* P- h2 Z" {5 z
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则