|
Tact 支持许多专为智能合约使用而定制的 原始数据类型。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。
8 I5 v5 T" i$ j! ^' h1 p3 W/ @3 O/ K% ^7 b+ A+ }
9 v4 _! z( L4 Z. Y1 B& |
6 |- a! Z: n: |4 g {; U& m* w% h结构
& I8 \2 A, v+ H0 O/ I" }, g$ ?结构体可以定义包含多个不同类型字段的复杂数据类型。 它们还可以嵌套。 它们还可以嵌套。
. ~4 ^/ n8 `" `5 g- struct Point {
6 x5 h5 A+ ~( D# k/ l5 G - x: Int as int64;$ c* p, w; q# k, O$ y1 `* P9 j* ?
- y: Int as int64;
: N4 j+ A0 @; w - }
) {% |- `: X; [- A
4 c+ D& M* V6 t$ m- struct Line {& d c4 o2 V: Q2 p2 f
- start: Point;
5 y* Q. f( P- [& n - end: Point;
: Q0 m; g) g" I& h% M1 ~$ Y* e - }
复制代码 结构体还可以包含默认字段,并定义可选类型的字段。 结构体还可以包含默认字段和定义[可选类型]字段(/book/optionals)。 如果您有很多字段,但又不想一直在 new instances 中为它们指定通用值,那么这将非常有用。
: L" c' s( u$ p& Z- struct Params {
1 ?7 E" d2 ]& P9 j0 ~ - name: String = "Satoshi"; // default value
# i9 r I+ n8 s* ~# U, z/ } - # O, G6 P5 U' i. q. f6 Q; B
- age: Int?; // field with an optional type Int?, a/ _ y& k; s' J- u( z4 \& u
- // and default value of null) l9 T1 q( t4 x. \0 P' X
- * @- ]- z8 S, e3 q1 `7 ^
- point: Point; // nested Structs
2 f& L/ j4 e1 U3 Z - }
复制代码 字段的顺序很重要,因为它与TL-B 模式 中的内存布局一致。 不过,与某些采用手动内存管理的语言不同,Tact 在字段之间没有任何填充。% [3 j) M1 f: Q$ r$ |$ l
. W3 H; G9 ]- P( R5 {
v |+ y! B+ j+ U: }# \ N$ x, ^7 S
消息
6 a9 p0 m; a* P6 f消息中可以包含 结构体:$ p& J* W4 ~* }3 j6 D
- struct Point {7 u {$ ^ L0 [, x, q
- x: Int;' R2 L/ H8 V _8 _6 H/ u
- y: Int;
8 U: n1 P1 ?$ K+ A - }' g; t+ C! s9 p7 x
( t5 K+ E9 x R% Q/ D% }- message Add {
' G; g" A B; z% g - point: Point; // holds a struct Point
' ^1 C# f0 L2 y% q4 f# d - }
复制代码- // This Message overwrites its unique id with 0x7362d09c* H, _: l, c) K" x7 f
- message(0x7362d09c) TokenNotification {
% [1 ?# [3 j# \0 ?) u" v8 A - forwardPayload: Slice as remaining;
- C3 t. t0 W: z - }
复制代码 这对于要处理特定智能合约的某些操作码(如 Jetton standard)的情况非常有用。 该合约能够处理的操作码简表为此处以 FunC 表示。 它们是智能合约的接口。
6 w w1 U1 a6 o6 s+ f% h! C9 D# L1 x, u( r
, O6 w2 J! c4 m( B3 ?操作
! a. \9 Z3 [' k8 d& e# |实例化
0 s4 G/ H" ^4 |: ^& l# `& u& ]创建 Struct 和 Message 实例类似于 function calls,但需要用大括号 {}(大括号)代替小括号 ()指定参数:
7 q' Z; }! C7 z- struct StA {
f' A" X1 q+ m, B; `' p' {& e1 ^ - field1: Int;
% I+ b5 y: `" h( X0 t - field2: Int;
" `- _3 d, v1 t2 K. y+ e - }- E6 x" @. a" B' J5 j" ?2 _
- % G2 ]% S1 k! s. ]9 r L
- message MsgB {
( B( Y2 y/ ?9 h - field1: String;
; S% R& a; @ ?: L: ?% Z - field2: String;
* v" j6 I3 f9 v U' I. } - }& O" ?5 V, B# u1 c
2 w9 s" X) f0 M2 {) `; u3 m- fun example() {; H P$ \" Q% U' I5 C" J
- // Instance of a Struct StA. k. d; t x: Y4 I3 [6 s
- StA{
7 J% U) h4 L0 i - field1: 42,
+ p$ u% s& n& }6 ^5 B) P7 e - field2: 68 + 1, // trailing comma is allowed) l4 O& ?3 K5 F/ [7 l% s4 i, ^
- };
' I, e/ A# y1 x% o0 t - h5 f- ?7 r' O& \3 Z& f
- // Instance of a Message MsgB
, W) r2 U1 y, g- n - MsgB{
/ M! _2 F" ~7 g4 U - field1: "May the 4th",
4 x$ W: H- M, q) O: l/ h4 J - field2: "be with you!", // trailing comma is allowed; R5 Q N; g' \
- };
+ B2 G8 W5 \0 ~- [- y - }
复制代码- struct PopQuiz { {% [' ]2 a+ V6 O5 Y; y6 k0 L" u
- vogonsCount: Int;+ X! t% m% q) T" F
- nicestNumber: Int;1 g' ~2 @/ ^. B/ n7 F
- }
& m) \) l& L A1 `
# M6 T6 w* p* ~6 f- fun example() {' J+ }* m4 j4 q( u: g2 i
- // Let's introduce a couple of variables
) u7 d/ ?( t0 q+ Z8 W ~ - let vogonsCount: Int = 42;
8 r0 j) q* O* j0 J4 T" c - let nicestNumber: Int = 68 + 1;8 X2 S( s- |# Z. g* s. y( D7 s" U
4 h8 w( S t6 u' V- // You may instantiate the Struct as usual and assign variables to fields,
. f* O; T/ z4 j- O - // but that is a bit repetitive and tedious at times; i) B# s3 i6 G$ h
- PopQuiz{ vogonsCount: vogonsCount, nicestNumber: nicestNumber };
5 {1 B9 x9 c4 L5 R3 S2 v
# g5 \9 r! @! v! o! i+ v- // Let's use field punning and type less,. l, r; k: B9 e& {" N2 Q9 s1 ?
- // because our variable names happen to be the same as field names4 N) e1 I. l1 \
- PopQuiz{8 k1 P6 e2 E, l( u* G+ O3 M
- vogonsCount," o; p# b" S/ E& x6 V! [! b4 f
- nicestNumber, // trailing comma is allowed here too!2 T3 Q! u+ m% c2 S/ h/ y4 A. v
- };, B; D& ^/ U) o) v' T* }. I
- }
复制代码- struct Big {* @* o/ H4 }$ j, W5 a
- f1: Int;
5 h6 k: [# f0 l3 D! l - f2: Int;4 u* R% ]5 R% r: i/ U8 V
- f3: Int;' S# H+ y8 H. e3 ~. k5 O
- f4: Int;9 V- c$ y, t9 d& `( v) d$ q
- f5: Int;
) c5 R$ z+ q l; v ?6 y - f6: Int;& I/ E5 W- q4 A
- }6 S7 e8 a! s9 C# B; K- G* w
- / B, ?. [ B* c- u/ @, `. f0 ~- I
- fun conversionFun() {2 O% m, F2 {$ b2 `- h
- dump(Big{; R& E: \6 E) c: U
- f1: 10000000000, f2: 10000000000, f3: 10000000000,* T* n/ i) ?# l4 J! U! N/ V
- f4: 10000000000, f5: 10000000000, f6: 10000000000,, U9 g) ]! W0 w `
- }.toCell()); // x{...cell with references...}# a( _. F" T2 o6 Q5 C# L% p
- }
复制代码- struct Fizz { foo: Int }' S1 G! H8 ]& o, ?0 R, g; M/ W G
- message(100) Buzz { bar: Int }
4 T3 s( K/ k1 A% w B- p! {
# U% [9 m& k& _1 ]- c$ }- fun constructThenParse() {
! F* E/ d6 L- G- I - let fizzCell = Fizz{foo: 42}.toCell();& @" g N! j/ N
- let buzzCell = Buzz{bar: 27}.toCell();! v; U* K/ I& v' \
- 2 T5 J: ?$ }. e4 f4 E+ F9 `1 n- X/ f, E
- let parsedFizz: Fizz = Fizz.fromCell(fizzCell);# T1 ~, j: e4 V9 O+ C& _; P
- let parsedBuzz: Buzz = Buzz.fromCell(buzzCell);1 P5 g- j7 V( A+ k# N
- }
复制代码- struct ArbitraryStruct {}' |# h# B/ p0 s4 i7 ^
- message(0x2A) ArbitraryMessage {}
! F# t. i* E1 `8 s! y t - $ f0 J& o) _* Q+ B- Z+ X# x
- fun lawOne() {
# c' R0 ], W) b" [8 F6 I - let structInst = ArbitraryStruct{};7 w, }/ B6 W; [$ {
- let messageInst = ArbitraryMessage{};
7 ^' a8 S' a, C- ]9 z( j
; d) z" Y' z X8 o- ArbitraryStruct.fromCell(structInst.toCell()); // = structInst& ?+ D/ d4 m1 v7 d1 f4 |! ^' Y
- ArbitraryMessage.fromCell(messageInst.toCell()); // = messageInst
6 {% r/ h9 r& }5 T; u1 s! W4 |6 ^
( K# T% y, X [3 F/ ^- // Same goes for Slices, with .toCell().asSlice() and .fromSlice()
! f7 G x& w, b, w - % v# k' W. @. V; D9 W
- ArbitraryStruct.fromSlice(structInst.toCell().asSlice()); // = structInst. @/ {& g" C8 V3 }7 S
- ArbitraryMessage.fromSlice(messageInst.toCell().asSlice()); // = messageInst
9 g% L1 f8 T7 _$ Z& L l( } - }
复制代码 对于任何与给定 Struct/Message 具有相同 TL-B 布局的 cell,调用 Struct.fromCell()(或 Message.fromCell()),然后通过 .toCell() 将结果转换为 Cell,就会得到原始 cell 的副本:- struct ArbitraryStruct { val: Int as uint32 }
" }6 {( |9 l2 U2 q - message(0x2A) ArbitraryMessage {}- g6 Q5 t- K4 }" @' f
- % l0 j+ m6 p9 F; k8 r/ I. H
- fun lawTwo() {
z! p7 n1 w% l7 |5 J J - // Using 32 bits to store 42 just so this cellInst can be. L1 Y5 a$ @- O# b9 `, _% j# J2 \/ F
- // re-used for working with both ArbitraryStruct and ArbitraryMessage. H" q6 t# q+ Y! R3 U
- let cellInst = beginCell().storeUint(42, 32).endCell();5 {( t4 Y4 A7 W& r; {
- ! s. f/ O; d* R3 \0 ^
- ArbitraryStruct.fromCell(cellInst).toCell(); // = cellInst
# e. G" B, t0 k) S; W# } - ArbitraryMessage.fromCell(cellInst).toCell(); // = cellInst( Y( ~' a( a, Z; E8 z
% W, p- x9 b& B( v- // Same goes for Slices, with .fromSlice() and .toCell().asSlice()
3 ]$ y% B) [6 i( q - let sliceInst = cellInst.asSlice();
: `1 B' D! |! ^$ D2 v" S0 a
" S. Z' x! \$ ]- ArbitraryStruct.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst
0 P+ s7 e" a3 g3 F& a+ i! a* D - ArbitraryMessage.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst
7 o* @9 t7 k8 \/ B2 w9 z! W - }
复制代码
) F5 \: y/ w1 O. d: }/ M7 V |
|