Reference Data Types
Learn about the features and uses of reference data types.
Reference data types
Reference data types don’t hold value directly; instead, they store the location of the data. With the help of reference types, two different variables can refer to the same location, and any modification made in one variable can affect the other one. We’ll demonstrate this soon. There are a number of reference types; let’s take a look at them.
Strings and bytes
Strings and bytes are special types of arrays in Solidity. The bytes
type is used to store a fixed-sized character set, while the string
data type is used to store a character set equal to or more than a byte. The string
type is equal to bytes
but doesn’t allow us to check its length or index access. This means that unlike in other languages, in Solidity we cannot use string.length
to check for the length of a string or string[3]
to get the character at index 3. However, this is possible with bytes
. The bytes
type also has the advantage of using less gas, so it’s better to use it when we know the data length. Increments go from bytes1
to bytes32
. Here’s how we can initialize strings and bytes in Solidity using string literals:
string testString = "hello"; // using double quotesstring testString2 = 'hello'; // using single quotesstring testString3 = 'hello' "world"; // same as "helloworld"// bytesbytes testBytes = "Any length of data";bytes1 testBytes2 = "a"; // just one charbytes5 testBytes3 = "abcde"; // 5 charbytes32 testBytes4 = "Any length of data up to 32 characters";
Strings and bytes can be concatenated by using string.concat(str1, str2, ...otherStr)
or bytes.concat(byte1, byte2, ...otherBytes)
. We can also convert from string
to bytes
and vice versa if we need to.
Structs
Structs in Solidity give us the ability to define new data types. Here, we can structure a new type that defines properties that can be of different types. This structure is a reference type variable that can include both value and reference. To define a new struct, we use the keyword struct
. Let’s demonstrate this using our Contacts contract.
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;/*** @title Contact* @dev Store & retrieve contacts of friends and family*/contract Contact {enum Relationship {Family,Friend,Acquaintance}struct ContactDetail {uint256 number;string name;address payable _address;bool isEmergencyContact;Relationship relationship;}address owner;constructor() {owner = msg.sender;}/*** @dev Save new contact* @param number_ number of contact to store* @param name_ name of contact to store* @param address_ blockchain address of contact to store* @param relationship_ relationship of contact to store*/function save(uint256 number_, string calldata name_, address payable address_, Relationship relationship_) public {// save contact}}
Instead of defining the various properties of a contact as global variables, we put them all in one new type we structured called ContactDetail
. This makes it easier ...