序列和数组映射
许多 UNO 接口使用序列及简单类型。在 OpenOffice.org Basic 中,与序列相对应的是数组。数组是 Basic 语言的标准元素。下面的示例说明了如何声明数组:
Dim a1( 100 ) ' Variant array, index range: 0-100 -> 101 elements Dim a2%( 5 ) ' Integer array, index range: 0-5 -> 6 elements Dim a3$( 0 ) ' String array, index range: 0-0 -> 1 element Dim a4&( 9, 19 ) ' Long array, index range: (0-9) x (0-19) -> 200 elements
Basic 中没有特殊的索引运算符,如 C++ 和 Java 中的 []。而是使用普通括号 () 访问数组元素:
Dim i%, a%( 10 ) for i% = 0 to 10 ' this loop initializes the array a%(i%) = i% next i% dim s$ for i% = 0 to 10 ' this loop adds all array elements to a string s$ = s$ + " " + a%(i%) next i% msgbox s$ ' Displays the string containing all array elements Dim b( 2, 3 ) b( 2, 3 ) = 23 b( 0, 0 ) = 0 b( 2, 4 ) = 24 ' Error ”Subscript out of range”
如示例所示,Dim
命令中的索引不同于 C++ 和 Java 数组声明。它们不是描述元素的数目,而是描述允许的最大索引。数组元素比给定索引多一个。这对于将 OpenOffice.org Basic 数组映射成 UNO 序列非常重要,因为 UNO 序列遵循 C++/Java 数组语义。
当 UNO API 需要一个序列时,Basic 程序员可以使用一个相应的数组。在以下示例中,oSequenceContainer
是一个对象,其具有一个类型为 sequence<short>
的属性 TheSequence
。要将一个长度为 10、值为 0, 1, 2, ...9 的序列指定给该属性,可以使用以下代码:
Dim i%, a%( 9 ) ' Maximum index 9 -> 10 elements for i% = 0 to 9 ' this loop initializes the array a%(i%) = i% next i% oSequenceContainer.TheSequence = a%() ' If “TheSequence” is based on XPropertySet alternatively oSequenceContainer.setPropertyValue( “TheSequence”, a%() )
Basic 程序员在编程时,需要了解不同的索引语义。在以下示例中,程序员传送包含一个元素的序
列,但实际上传送了两个元素:
' Pass a sequence of length 1 to the TheSequence property: Dim a%( 1 ) ' WRONG: The array has 2 elements, not only 1! a%( 0 ) = 3 ' Only Element 0 is initialized, ' Element 1 remains 0 as initialized by Dim ' Now a sequence with two values (3,0) is passed what ' may result in an error or an unexpected behavior! oSequenceContainer.setPropertyValue( “TheSequence”, a%() )
使用一个称为 Array()
的 OpenOffice.org Basic RTL 函数,通过一步就可以创建、初始化数组并将它指定给 Variant
变量,这非常有用,尤其是对于小型序列:
Dim a ' should be declared as Variant a = Array( 1, 2, 3 ) ' is the same as Dim a(2) a( 0 ) = 1 a( 1 ) = 2 a( 2 ) = 3
有时,有必要将空序列传送到 UNO 接口。在 Basic 中,可以通过在 Dim 命令中忽略索引来声明空序列:
Dim a%() ' empty array/sequence of type Integer Dim b$() ' empty array/sequence of String
UNO 返回的序列在 Basic 中也表示为数组,但不必事先声明这些数组。应该将用于接受序列的变量声明为 Variant
。要访问 UNO 返回的数组,需要获得有关 Basic RTL 函数 LBound()
和 UBound()
所包含的元素数目的信息。
函数 LBound()
返回下限索引,而 UBound()
返回上限索引。以下代码示意了一个循环,该循环将遍历所返回序列的所有元素:
Dim aResultArray ' should be declared as Variant aResultArray = oSequenceContainer.TheSequence dim i%, iFrom%, iTo% iFrom% = LBound( aResultArray() ) iTo% = UBound( aResultArray() ) for i% = iFrom% to iTo% ' this loop displays all array elements msgbox aResultArray(i%) next i%
函数 LBound()
是一个标准的 Basic 函数,而不是 UNO 上下文中所特有的。Basic 数组不必从索引 0 开始,因为可能写入如下所示的内容:
Dim a (3 to 5 )
这使数组的下限索引为 3。但是,UNO 返回序列的索引通常从 0 开始。一般仅使用 UBound()
,这时上面的示例可以简化为:
Dim aResultArray ' should be declared as Variant aResultArray = oSequenceContainer.TheSequence Dim i%, iTo% iTo% = UBound( aResultArray() ) For i% = 0 To iTo% ' this loop displays all array elements MsgBox aResultArray(i%) Next i%
序列/数组的元素数目非常容易计算:
u% = UBound( aResultArray() ) ElementCount% = u% + 1
对于空数组/序列,UBound
返回 -1。这样,随后按如下所示计算元素数目时,UBound
的语义就可以保持一致:
ElementCount% = u% + 1' = -1 + 1 = 0
UNO 序列与 Basic 数组之间的映射前提二者都使用一个基于零的索引系统。为了避免出现问题,不要使用语法
Dim a ( IndexMin to IndexMin ) 或 Basic 命令 |
UNO 还支持包含序列的序列。在 Basic 中,这对应于包含数组的数组。不要将包含序列的序列与多维数组相混淆。在多维数组中,所有子数组始终具有相同数目的元素,而在包含序列的序列中,每个序列可以具有不同的大小。示例:
Dim aArrayOfArrays ' should be declared as Variant aArrayOfArrays = oExample.ShortSequences ' returns a sequence of sequences of short Dim i%, NumberOfSequences% Dim j%, NumberOfElements% Dim aElementArray NumberOfSequences% = UBound( aArrayOfArrays() ) + 1 For i% = 0 to NumberOfSequences% - 1' loop over all sequences aElementArray = aArrayOfArrays( i% ) NumberOfElements% = UBound( aElementArray() ) + 1 For j% = 0 to NumberOfElements% - 1 ' loop over all elements MsgBox aElementArray( j% ) Next j% Next i%
要在 Basic 中创建一个包含数组的数组,可以将子数组作为主数组的元素::
' Declare master array Dim aArrayOfArrays( 2 ) ' Declare sub arrays Dim aArray0( 3 ) Dim aArray1( 2 ) Dim aArray2( 0 ) ' Initialise sub arrays aArray0( 0 ) = 0 aArray0( 1 ) = 1 aArray0( 2 ) = 2 aArray0( 3 ) = 3 aArray1( 0 ) = 42 aArray1( 1 ) = 0 aArray1( 2 ) = -42 aArray2( 0 ) = 1 ' Assign sub arrays to the master array aArrayOfArrays( 0 ) = aArray0() aArrayOfArrays( 1 ) = aArray1() aArrayOfArrays( 2 ) = aArray2() ' Assign the master array to the array property oExample.ShortSequences = aArrayOfArrays()
在这种情况下,运行时函数 Array()
非常有用。这样,示例代码就可以变得更加简练:
' Declare master array Dim aArrayOfArrays( 2 ) ' Create and assign sub arrays aArrayOfArrays( 0 ) = Array( 0, 1, 2, 3 ) aArrayOfArrays( 1 ) = Array( 42, 0, -42 ) aArrayOfArrays( 2 ) = Array( 1 ) ' Assign the master array to the array property oExample.ShortSequences = aArrayOfArrays()
如果嵌套使用 Array()
,就可以编写更简练的代码,但会使得人们难以理解将要生成的数组:
' Declare master array variable as variant Dim aArrayOfArrays ' Create and assign master array and sub arrays aArrayOfArrays = Array( Array( 0, 1, 2, 3 ), Array( 42, 0, -42 ), Array( 1 ) ) ' Assign the master array to the array property oExample.ShortSequences = aArrayOfArrays()
对于更高阶次的序列,也可以进行相应处理。
Content on this page is licensed under the Public Documentation License (PDL). |