1# `cty` types 2 3This page covers in detail all of the primitive types and compound type kinds supported within `cty`. For more general background information, see 4[the `cty` overview](./concepts.md). 5 6## Common Operations and Integration Methods 7 8The following methods apply to all values: 9 10* `Type` returns the type of the value, as a `cty.Type` instance. 11* `Equals` returns a `cty.Bool` that is `cty.True` if the receiver and the 12 given other value are equal. This is an operation method, so its result 13 will be unknown if either argument is unknown. 14* `RawEquals` is similar to `Equals` except that it doesn't implement the 15 usual special behavior for unknowns and dynamic values, and it returns a 16 native Go `bool` as its result. This method is intended for use in tests; 17 `Equals` should be preferred for most uses. 18* `IsKnown` returns `true` if the receiver is a known value, or `false` 19 if it is an unknown value. 20* `IsNull` returns `true` if the receiver is a null value, or `false` 21 otherwise. 22 23All values except capsule-typed values can be serialized with the builtin 24Go package `encoding/gob`. Values can also be used with the `%#v` pattern 25in the `fmt` package to print out a Go-oriented serialization of the 26value. 27 28## Primitive Types 29 30### `cty.Number` 31 32The number type represents arbitrary-precision floating point numbers. 33 34Since numbers are arbitrary-precision, there is no need to worry about 35integer overflow/underflow or loss of precision during arithmetic operations. 36However, eventually a calling application will probably want to convert a 37number to one of the Go numeric types, at which point its range will be 38constrained to fit within that type, generating an error if it does not fit. 39 40The following additional operations are supported on numbers: 41 42* `Absolute` converts a negative value to a positive value of the same 43 magnitude. 44* `Add` computes the sum of two numbers. 45* `Divide` divides the receiver by another number. 46* `GreaterThan` returns `cty.True` if the receiver is greater than the other 47 given number. 48* `GreaterThanOrEqualTo` returns `cty.True` if the receiver is greater than or 49 equal to the other given number. 50* `LessThan` returns `cty.True` if the receiver is less than the other given 51 number. 52* `LessThanOrEqualTo` returns `cty.True` if the receiver is less than or 53 equal to the other given number. 54* `Modulo` computes the remainder from integer division of the receiver by 55 the other given number. 56* `Multiply` computes the product of two numbers. 57* `Negate` inverts the sign of the number. 58* `Subtract` computes the difference between two numbers. 59 60`cty.Number` values can be constructed using several different factory 61functions: 62 63* `NumberVal` creates a number value from a `*big.Float`, from the `math/big` package. 64* `NumberIntVal` creates a number value from a native `int64` value. 65* `NumberUIntVal` creates a number value from a native `uint64` value. 66* `NumberFloatVal` creates a number value from a native `float64` value. 67 68The core API only allows extracting the value from a known number as a 69`*big.Float` using the `AsBigFloat` method. However, 70[the `gocty` package](./gocty.md) provides a more convenient way to convert 71numbers to any native Go number type, with automatic range checking to ensure 72that the value fits into the target type. 73 74The following numbers are provided as package variables for convenience: 75 76* `cty.Zero` is the number zero. 77* `cty.PositiveInfinity` represents positive infinity as a number. All other 78 numbers are less than this value. 79* `cty.NegativeInfinity` represents negative infinity as a number. All other 80 numbers are greater than this value. 81 82### `cty.String` 83 84The string type represents a sequence of unicode codepoints. 85 86There are no additional operations supported for strings. 87 88`cty.String` values can be constructed using the `cty.StringVal` factory 89function. The native Go `string` passed in must be a valid UTF-8 sequence, 90and it will be normalized such that any combining diacritics are converted 91to precomposed forms where available. (Technically-speaking, the mapping 92applied is the NFC normalization as defined in the relevant Unicode 93specifications.) 94 95The `AsString` method can be called on a string value to obtain the native 96Go `string` representation of a known string, after normalization. 97 98### `cty.Bool` 99 100The bool type represents boolean (true or false) values. 101 102The following additional operations are supported on bool values: 103 104* `And` computes the logical AND operation for two boolean values. 105* `Not` returns the boolean opposite of the receiver. 106* `Or` computes the logical OR operation for two boolean values. 107 108Calling applications may either work directly with the predefined `cty.True` 109and `cty.False` variables, or dynamically create a boolean value using 110`cty.BoolVal`. 111 112The `True` method returns a native Go `bool` representing a known boolean 113value. The `False` method returns the opposite of it. 114 115## Collection Type Kinds 116 117`cty` has three different kinds of collection type. All three of them are 118parameterized with a single _element type_ to produce a collection type. 119The difference between the kinds is how the elements are internally organized 120and what operations are used to retrieve them. 121 122### `cty.List` types 123 124List types are ordered sequences of values, accessed using consecutive 125integers starting at zero. 126 127The following operations apply to values of a list type: 128 129* `Index` can be passed an integer number less than the list's length to 130 retrieve one of the list elements. 131* `HasIndex` can be used to determine if a particular call to `Index` would 132 succeed. 133* `Length` returns a number representing the number of elements in the list. 134 The highest integer that can be passed to `Index` is one less than this 135 number. 136 137List types are created by passing an element type to the function `cty.List`. 138List _values_ can be created by passing a type-homogenous `[]cty.Value` 139to `cty.ListVal`, or by passing an element type to `cty.ListValEmpty`. 140 141The following integration methods can be used with known list-typed values: 142 143* `LengthInt` returns the length of the list as a native Go `int`. 144* `ElementIterator` returns an object that can be used to iterate over the 145 list elements. 146* `ForEachElement` runs a given callback function for each element. 147 148### `cty.Map` types 149 150Map types are collection values that are each assigned a unique string key. 151 152The following operations apply to values of a map type: 153 154* `Index` can be passed a string value to retrieve the corresponding 155 element. 156* `HasIndex` can be used to determine if a particular call to `Index` would 157 succeed. 158* `Length` returns a number representing the number of elements in the map. 159 160Map types are created by passing an element type to the function `cty.Map`. 161Map _values_ can be created by passing a type-homogenous `map[string]cty.Value` 162to `cty.MapVal`, or by passing an element type to `cty.MapValEmpty`. 163 164The following integration methods can be used with known map-typed values: 165 166* `LengthInt` returns the number of elements as a native Go `int`. 167* `ElementIterator` returns an object that can be used to iterate over the 168 map elements in lexicographical order by key. 169* `ForEachElement` runs a given callback function for each element in the 170 same order as the `ElementIterator`. 171 172### `cty.Set` types 173 174Set types are collection values that model a mathematical set, where every 175possible value is either in or out of the set. Thus each set element value is 176its own identity in the set, and a given value cannot appear twice in the same 177set. 178 179The following operations apply to values of a set type: 180 181* `HasIndex` can be used to determine whether a particular value is in the 182 receiving set.. 183* `Length` returns a number representing the number of elements in the set. 184* `Index` is not particularly useful for sets, but for symmetry with the 185 other collection types it may be passed a value that is in the set and it 186 will then return that same value. 187 188Set types are created by passing an element type to the function `cty.Set`. 189Set _values_ can be created by passing a type-homogenous `[]cty.Value` to 190`cty.SetVal`, though the result is undefined if two values in the slice are 191equal. Alternatively, an empty set can be constructed using `cty.SetValEmpty`. 192 193The following integration methods can be used with known set-typed values: 194 195* `LengthInt` returns the number of elements as a native Go `int`. 196* `ElementIterator` returns an object that can be used to iterate over the 197 set elements in an undefined (but consistent) order. 198* `ForEachElement` runs a given callback function for each element in the 199 same order as the `ElementIterator`. 200 201Set membership is determined by equality, which has an interesting consequence 202for unknown values. Since unknown values are never equal to one another, 203theoretically an infinite number of unknown values can be in a set (constrained 204by available memory) but can never be detected by calls to `HasIndex`. 205 206A set with at least one unknown value in it has an unknown length, because the 207unknown values may or may not match each other (and thus coalesce into a single 208value) once they become known. However, if a set contains a mixture of known 209and unknown values then `HasIndex` will return true for those values because 210they are guaranteed to remain present no matter what final known value each 211of the unknown values takes on. 212 213## Structural Types 214 215`cty` has two different kinds of structural type. They have in common that 216they combine a number of values of arbitrary types together into a single 217value, but differ in how those values are internally organized and in which 218operations are used to retrieve them. 219 220### `cty.Object` types 221 222Object types each have zero or more named attributes that each in turn have 223their own type. 224 225The following operation applies to values of an object type: 226 227* `GetAttr` returns the value of an attribute given its name. 228 229The set of valid attributes for an object type can be inspected using the 230following methods on the type itself: 231 232* `AttributeTypes` returns a `map[string]Type` describing the types of all of 233 the attributes. 234* `AttributeType` returns the type of a single attribute given its name. 235* `HasAttribute` returns `true` if the type has an attribute with the given 236 name. 237 238Object types are constructed by passing a `map[string]Type` to `cty.Object`. 239Object _values_ can be created by passing a `map[string]Value` to 240`cty.ObjectVal`, in which the keys and value types define the object type 241that is implicitly created for that value. 242 243The variable `cty.EmptyObject` contains the object type with no attributes, 244and `cty.EmptyObjectVal` is the only non-null, known value of that type. 245 246There is **currently-experimental** support for creating object types where 247one or more attributes is annotated as being "optional", using the alternative 248constructor `cty.ObjectWithOptionalAttrs`. The behavior of that function or 249of any other function working with its result is subject to change even in 250future minor versions of `cty`. The optional-attribute annotations are 251considered only during type conversion, so for more information refer to 252the guide [Converting between `cty` types](convert.md). 253 254### `cty.Tuple` types 255 256Tuple types each have zero or more elements, each with its own type, arranged 257in a sequence and accessed by integer numbers starting at zero. 258 259A tuple type is therefore somewhat similar to a list type, but rather than 260representing an arbitrary number of values of a single type it represents a 261fixed number of values that may have _different_ types. 262 263The following operations apply to values of a tuple type: 264 265* `Index` can be passed an integer number less than the tuple's length to 266 retrieve one of the tuple elements. 267* `HasIndex` can be used to determine if a particular call to `Index` would 268 succeed. 269* `Length` returns a number representing the number of elements in the tuple. 270 The highest integer that can be passed to `Index` is one less than this 271 number. 272 273Tuple types are created by passing a `[]cty.Type` to the function `cty.Tuple`. 274Tuple _values_ can be created by passing a `[]cty.Value` to `cty.TupleVal`, 275in which the value types define the tuple type that is implicitly created 276for that value. 277 278The variable `cty.EmptyTuple` contains the tuple type with no elements, 279and `cty.EmptyTupleVal` is the only non-null, known value of that type. 280 281The following integration methods can be used with known tuple-typed values: 282 283* `LengthInt` returns the length of the tuple as a native Go `int`. 284* `ElementIterator` returns an object that can be used to iterate over the 285 tuple elements. 286* `ForEachElement` runs a given callback function for each element. 287 288## The Dynamic Pseudo-Type 289 290The dynamic pseudo-type is not a real type but is rather a _placeholder_ for 291a type that isn't known. 292 293One consequence of this being a "pseudo-type" is that there is no known, 294non-null value of this type, but `cty.DynamicVal` is the unknown value of 295this type, and a null value without a known type can be represented by 296`cty.NullVal(cty.DynamicPseudoType)`. 297 298This pseudo-type serves two similar purposes as a placeholder type: 299 300* When `cty.DynamicVal` is used in an operation with another value, the 301 result is either itself `cty.DynamicVal` or it is an unknown value of 302 some suitable type. This allows the dynamic pseudo-type to be used as 303 a placeholder during type checking, optimistically assuming that the 304 eventually-determined type will be compatible and failing at that 305 later point if not. 306* `cty.DynamicPseudoType` can be used with the type `TestConformance` method 307 to declare that any type is permitted in the type being tested for 308 conformance. 309 310`cty` doesn't have _sum types_ (i.e. union types), so `cty.DynamicPseudoType` 311can be used also to represent situations where two or more specific types are 312allowed, under the assumption that more specific type checking will be done 313within the calling application's own logic even though it cannot be expressed 314directly within the `cty` type system. 315 316## Capsule Types 317 318Capsule types are a special kind of type that allows a calling application to 319"smuggle" otherwise-unsupported Go values through the `cty` type system. 320 321Such types and their associated values have no defined meaning in `cty`. The 322interpreter for a language building on `cty` might use capsule types for 323passing language-specific objects between functions provided in that language. 324 325A capsule type is created using the function `cty.Capsule`, which takes a 326"friendly name" for the type along with a `reflect.Type` that defines what 327type of Go value will be encapsulated in values of this type. A capsule-typed 328value can then be created by passing the capsule type and a pointer to a 329native value of the encapsulated type to `cty.CapsuleVal`. 330 331The integration method `EncapsulatedValue` allows the encapsulated data to 332then later be retrieved. 333 334Capsule types compare by reference, so each call to `cty.Capsule` produces 335a distinct type. Capsule _values_ compare by pointer equality, so two 336capsule values are equal if they have the same capsule type and they 337encapsulate a pointer to the same object. 338 339Due to the strange nature of capsule types, they are not totally supported 340by all of the other packages that build on the core `cty` API. They should 341be used with care and the documentation for other packages should be consulted 342for information about caveats and constraints relating to their use. 343 344It's possible for a calling application to write additional logic to make 345capsule types support a subset of operations that are generally expected to 346work for values of any type. For more information, see 347[capsule type operation definitions](./capsule-type-operations.md). 348