Adventures in UWP – Getting Started

For a while now I’ve wanted to do something in UWP (Universal Windows Platform).

UWP always gives me the “uncanny valley” sort of feeling; it looks like WPF and looks like a standard Windows .NET application, but it also has that feeling on the unknown about it. To illustrate what I mean, UWP application compile to an EXE, but anyone used to Windows programming will probably double click on the EXE and find that Windows responds with a message box stating “This application can only run in the context of an app container”.

We’ll cover this soon enough, but let’s start our adventure with the classic Hello World type example and look at the basic parts of a UWP application and using Visual Studio 2017 to run the application etc.

Versions etc.

First off, I’m using Windows 10.0.15063.0 and Visual Studio 2017, version 15.2 (26430.16). I state this upfront because I’ve found books/posts talking about previous versions telling us to expect this file and this dialog when creating a new project, so what you see may differ from what I describe here, depending upon your versions.

Creating our project

In Visual Studio, carry out the following

  1. File | New Project
  2. Visual C# | Windows Universal
  3. Select Blank App (Universal Windows)
  4. Name it HelloWorld
  5. You’ll be prompted to choose a target version and minimum version, leave these as defaulted for now

Navigating the project

Properties

Within the Properties section is the usual AssemblyInfo.cs, but also the Default.rd.xml. This is used to contain runtime directives (hence .rd.). This allows us to specify elements within our program that are available for reflection.

Reference

Unlike non-UWP applications, the References have only two items (excluding the Analyzers). Microsoft.NETCore.UniversalWindowsPlatform and Universal Windows.

Assets

By default the Assets folder contains seven png images. Including store logo and splash screen. These are templates (if you like) for your own images. Every one of the images is a square with a cross in it – so you’ll know pretty quickly if you’ve not supplied an image/logo/splash screen for some area.

App.xaml

Like WPF, we have an App.xaml (and ofcourse the App.xaml.cs code behind). The code behind has a fair bit more code within it, unlike WPF. Default code is there for us to handle state loading during the application launch, a point to save state when the application is suspended etc. Also, unlike WPF, the MainWindow (in this case MainPage) is navigated to via the OnLaunched code as opposed to being declared in the App.xaml file like WPF.

HelloWorld_TemporaryKey.pfx

A temporary key is created for us. As UWP is aimed at being downloaded and installed from the Windows Store (or side loaded) this requires the application to be signed, hence we’re given the starting point for this.

MainPage.xaml

MainPage.xaml and it’s code behind contain minimal XAML and code (like a standard WPF control). UWP tends to class these controls as Pages (reminds me of Silverlight).

Package.appxmanifest

Finally we come to the application manifest. This allows us to set up things like the application’s display name, the rotations supported (for tablet/phone type devices). We can assign our assets to specific scenarios, such as for tiles, app. icons and so on. We’ll also need to declare what capabilities the application needs access to. Sort of standard mobile phone development requirements, i.e. this application will require Bluetooth etc.

Note: It’s best to reduce the capabilities to the bare minimum required as some user’s may prefer to lock down the access an application has.

What happens if we run the application now?

So if we want to run the application, you’ll notice that (at least on my install of Visual Studio) there the run button on the toolbar with Local Machine shown (mine’s also defaulted to x86 instruction set). From the drop down we also have Simulator, Remote Machine, Device as well as a bunch of Mobile Emulators of different screen sizes.

The emulators obviously allow us to view our application on a mobile phone or tablet like sized device.

Remote Machine allows us to run the application remotely, so for example on a Windows tablet, but without needing to install it directly etc.

The simulator is a virtual device or maybe better thought of as a remote desktop. The odd thing is that you’re really remote desktop-ing into your own machine, so changes to the simulator affect your machine.

So, let’s choose Local Machine, then we’re doing the equivalent of running a “standard” windows application. You’ll notice a square with a cross in it displayed, this is the SplashScreen.scale-200.png supplied by the project template within our Assets folder. Change this and then re-run to confirm.

Once running our application is, as expected, a blank application, but before we move onto actually writing some code/designing the UI, when we ran the application Visual Studio actually installed the application for us in the Start Menu, under Recently Added you should see HelloWorld (if you followed my naming for the application). If you attempt the run the EXE within the build folder, you’ll get the message box stating “This application can only run in the context of an app container”, however from the Start Menu, the application will be correctly run from a container.

Finally for this section, when you run the application via Visual Studio you’ll see four icons on your main page, these include tools to view the visual tree of a selected item at runtime and enable selected option, display layout adorners and a track focused element tool.

These, by default, are hidden outside of the debugger, but we can also hide within the debugger experience by selecting Tools | Options | Debugging | General, then locate Enable UI Debugging Tools for XAML and deselect this option.

The splash screen

As mentioned previously, we define the splash screen image (or edit the existing) within the Assets, as this is assigned via the manifest. UWP automatically displays the splash screen for us over the application Window and within App.xaml.cs, the OnLaunched method, when Window.Current.Activate() is called, the splash screen will be removed (obviously it will not immediately happen as the Windows message will need to be sent through, but it’s at this point the UWP application then “properly” starts your application. Hence within OnLaunched, is the place to restore state or setup anything prior to the splash screen being removed.

Note: Like Windows Services, your application is expected to start within a certain amount of time or it’s perceived as failing to start. I’ve read this time is approximately 15 seconds. So you’ll need to be a little more creative if loading your application takes longer than this, i.e. run code on a non-blocking thread or simply lazy load state etc.

The Humanizer

I don’t really have much to say about the Humanizer library that’s not already written on their Github readme.

This post is more of a reminder post, just to remind me about the library because the name of it eluded me the other day when I wanted to use it.

So what is Humanizer?

If you’ve got strings, enums, dates, times (and more) that you need to convert to a more human readable string, then Humanizer can help. Equally if you have a string that you want to make less human readable you can use Humanizer (bare with me, the less human readable might be of use).

An example

I’ll use the real world scenario I needed to use Humanizer on.

I have data coming from a web service which returns field/property names and values. The names are in standard camel case, i.e. eligibilityFlag. Now this is fine, but I wanted the end user to see these names in a more human readable way, i.e. “eligibilityFlag” should display as “Eligibility flag”. It’s just nicer, looks better and is more readable for the end user.

Ofcourse, it’s not too difficult to write the code to do this yourself, but why bother when you can fire up Nuget or the Package Manager Console and locate the Humanizer package or run Install-Package Humanizer.

Just using the following

// don't forget using Humanizer

Console.WriteLine("eligibilityFlag".Humanize());

and the output will be Eligibility flag.

We can easily convert this back to the camel case computer style text using

Console.WriteLine("Eligibility flag".Dehumanize().Camelize());

Humanizer can also help with numbers to strings, for example convert numbers to works or to an easier to read format. If we have the value 123456 we might like to output and 123.456K or maybe as one hundred and twenty-three thousand four hundred and fifty-six using

Console.WriteLine(123456.ToWords());
Console.WriteLine(123456.ToMetric());

we can convert the metric representation back using

Console.WriteLine("123.456k".FromMetric());

Folding expressions in C++ 17

Setup your dev tools to use C++ 17

Using CLion (or CMake) and setting the CMakeLists.txt CMAKE_CXX_STANDARD to

set(CMAKE_CXX_STANDARD 17)

allows us to use C++ 17 features.

In CLion the intellisense/editor will show folding expressions with red underlines, i.e. as errors in the current release, however the code will compile

Folding Expressions

Basically folding expressions allow us to write code which takes one or more arguments and applies operators to them to create a return value.

In C++ terms, folding expressions take variadic template arguments and unpack the arguments using unary or binary operators to create a return value.

The syntax for folding expressions, is as follows

Syntax (as taken from http://en.cppreference.com/w/cpp/language/fold).

  • unary right fold (pack op …)
  • unary left fold (… op pack)
  • binary right fold (pack op … op init)
  • binary left fold (init op … op pack)

Let’s look at some examples to make things clearer using this syntax.

Unary right fold

The following is a simple summation method using unary right fold syntax

template<typename... Args>
auto unary_right_fold(Args... args) {
    return (args + ...);
}

Unary left fold

The following is a simple summation method using unary left fold syntax

template<typename... Args>
auto unary_left_fold(Args... args) {
    return (... + args);
}

Binary right fold

The following is a simple summation + 1 method using binary left fold syntax

template<typename... Args>
auto binary_right_fold(Args... args) {
    return (args + ... + 1);
}

Binary left fold

The following is a simple 1 + summation method using binary left fold syntax

template<typename... Args>
auto binary_left_fold(Args... args) {
    return (1 + ... + args);
}

threads, promises, futures, async, C++

The only C++ application I now maintain used a single thread to handle background copying and it was fine, but anything more than that and it becomes a little more complex to maintain, especially when compared to threading in C#, such as TPL, Parallel library and async/await.

Now whilst these new features/libraries are not in the same “ease of use” area as those C# classes etc. they are nevertheless a massive step forward.

From what I can tell, we have four different multi-threaded operations (I think that’s the best way to put it). I’m not talking locking, or other forms of synchronization here.

std::thread

So at the most basic level we have the std::thread which is extremely simple to use, here’s an example

auto t = std::thread([]
{
   // do something in a thread
});

We can block (or wait) until the thread has completed using t.join();, but there’s other possibilities for interacting with our thread.

std::future and std::promise

Futures and promises are two sides of the same coin, so to speak. A promise allows us to return state from a thread. Whereas a future is for reading that returned state.

In other words, let’s think of it in this, fairly simple way – we create a promise that really says that at some time there will be a state change or return value from thread. The promise can be used to get a std::future, which is the object that gives us this return result.

So we’ve got the equivalent of a simple producer/consumer pattern

auto promise = std::promise<std::string>();
auto producer = std::thread([&]
{
   // simulate some long-ish running task
   std::this_thread::sleep_for(std::chrono::seconds(5));
   promise.set_value("Some Message");
});

auto future = promise.get_future();
auto consumer = std::thread([&]
{
   std::cout << future.get().c_str();
});

// for testing, we'll block the current thread
// until these have completed
producer.join();
consumer.join();

Note: In the example above I’m simply using a lambda and passing reference to all variables in scope via the capture, using [&], as a capture list is required to access the promise and future outside of the lambdas.

In this example code we simply create a promise and then within the first thread we’re simulating a long-ish running task with the sleep_for method. Once the task is complete we set_value on the promise which causes the future.get() to unblock, but we’ve jumped ahead of ourselves, so…

Next we get the future (get_future) from the promise and to simulate a a producer/consumer we spin up another thread to handle any return from the promise via the future.

In the consumer thread, the call to future.get() will block that thread until the promise has been fulfilled.

Finally, the code calls producer.join() and consumer.join() to block the main thread until both producer and consumer threads have completed.

std::async

The example for the promise/future combination to create a producer consumer can be simplified further using the std::async which basically deals with creating a thread and creating a future for us. So let’s see the code for the producer/consumer now with the std::async

std::future<std::string> future = std::async([&]
{
   std::this_thread::sleep_for(std::chrono::seconds(5));
   return std::string("Some Message");
});

auto consumer = std::thread([&]
{
   std::cout << future.get().c_str();
});

consumer.join();

In the above we’ve done away with the promise and the first thread which have both been replaced with the higher level construct, std::async. We’ve still got a future back and hence still call future.get() on it, but notice how we’ve also switch to returning the std::string and the future using the template argument to match the returned type.

We’re not actually sure if the code within the async lambda is run on a new thread or run on the calling thread, as the async documentation states…

“The template function async runs the function f asynchronously (potentially in a separate thread which may be part of a thread pool) and returns a std::future that will eventually hold the result of that function call.”

So the async method may run the code on a thread or deferred. Deferred meaning the code is run when we call the future’s get method in a “lazy” manner.

We can stipulate whether to run on a thread or as deferred using an std::async overload

std::future<std::string> future = 
   std::async(std::launch::deferred, [&]
   {
   });

In the above we’ve deferred the async call and hence it’ll be run on the calling thread, alternatively we could stipulate std::launch::async, see std::launch.

What about exceptions?

If an exception occurs in async method or the promise set_exception is called in our producer/consumer using a promise. Then we need to catch the exception in the future (call to get()). Hence here’s an example of the async code with an exception occuring

std::future<std::string> future = std::async([&]
{
   throw std::exception("Some Exception");
   return std::string("Some Message");
});

auto consumer = std::thread([&]
{
   try
   {
      std::cout << future.get().c_str();
   }
   catch(std::exception e)
   {
      std::cout << e.what();
   }
});

consumer.join();

Here we throw an exception in the async lambda and when future.get is called, that exception is propagated through to the consumer thread. We need to catch it here and handle it otherwise it will leak through to the application and potentially crash the application if not handled elsewhere.

Variadic template arguments in C++

We’ve had varargs forever in C/C++ but variadic templates allow us to use strongly types variadic arguments.

We’re going to create a simple container (which just wraps a vector) and then extend this with variadic template arguments

template<typename T>
class container
{
   std::vector<T> _values;
public:
};

Now we want to add a push_back method which allows us to pass in multiple values, so the code would look like this

container<int> c;
c.push_back(1, 2, 3);

If we declare a public method which looks like this

template<typename ...Args>
void push_back(Args... args)
{
}

we can see the …Args in the template, these are variadic template arguments and you can see from the push_back parameters how we might use this.

But how do we get the variables 1, 2 & 3 that were passed as arguments? Unfortunately these are not translated to an array or similar, but we can use recursion and a change in our method signature to solve this.

Here’s the code

template<typename ...Args>
void push_back(T v, Args... args)
{
   _values.push_back(v);
   push_back(args...);
}

With this the calling code c.push_back(1, 2, 3); is actually passing to the push_back method the equivalent of push_back(int, variable arguments), so the first item is assign to argument v and the 2 & 3 to to args. Now using recursion we can “unpack” the args with the call push_back(args…), however this will not compiler because at some point the variable args will be empty, i.e. there’s no push_back method which takes no arguments. So we need to add the followin

static void push_back() {}

as a private method and this acts as a recursive terminator method. i.e. called when no arguments exist and causes the recursion to complete and allows the stack to unwind.

Ofcourse an alternative to variable arguments is to use the std::initializer_list (as discussed in a previous post), so the calling code might now look like this

container<int> c;
c.push_back({ 1, 2, 3 });

From our example class, remove the push_back methods and replace with

void push_back(std::initializer_list<T> il)
{
   for(auto it = il.begin(); it != il.end(); ++it)
   {
      _values.push_back(*it);
   }
}

Obviously the variable template arguments looks a lot more natural but may not suit every use.

Note: The variadic argument templates are also used in C++ folding expressions, which I will discuss in a subsequent post.

Whilst the example container was handling a single generic type, we could (as you can see from the push_back methods) create methods that handle different types. Let’s assume we have a simple type_checker class, which outputs what each argument type is, we could write the following

class type_checker
{
   static void what() {}
public:
   template<typename ...Args>
   void what(int v, Args... args)
   {
      std::cout << "Int " << v << std::endl;
      what(args...);
   }

   template<typename ...Args>
   void what(std::string v, Args... args)
   {
      std::cout << "String " << v.c_str() << std::endl;
      what(args...);
   }
};

// calling code

type_checker c;
c.what(1, "Hello", 3);

Now we’re passing in heterogeneous data and depending upon the first argument type each time to choose the correct overload method. The variadic arguments are unpacked and again the correct overload will be called.

To understand this more clearly, the c.what(1, “Hello”, 3);
line of code in this example will call the what methods as follows.

The what(int, …) is called first followed by what(std::string, …) followed by what(int, …) and finally what().

More on initializer lists in C++

Initializer lists in C++ allow us to intialize arrays/vectors and more using a simple syntax, for example

std::vector<std::string> v = { "one", "two", "three" };

This will create a vector with three values “one”, “two” and “three”.

This works because an intializer list (i.e. the { “one”, “two”, “three” } in this example, is actually a std::initializer_list type and the vector has an overload = operator which accepts such a type and then copies the values into the vector. So the { } syntax is really just syntactic sugar.

Here’s the same code but showing the explicit use of the type, i.e. we create a std::initializer_list

std::initializer_list<int> il = { 1, 2, 3 };
// which is the same as this, with an auto
auto il = { 1, 2, 3 };

Knowing, as we do, that the initializer list will in fact create a std::initializer_list, it’s obvious that this will come with a slight overhear in terms of creating a std::initializer_list, then when assigned to a vector/array or the likes, we need to loop through the items in the list and copy into the vector. Hence if out and out speed and member use is an issue, one might prefer not to use such syntax.

We can also use an initializer list with a single value, for example

auto i{ 3 };

and this resolves to an int type with the value 3.

Pointers to functions, easier than they used to be…

For this post, I wanted to implement a callback in C++.

A method I have does some work (copying files) which might take minutes to complete and whilst copying the files it posts updates back to the callback telling the calling method of the progress, i.e. the file that’s being copied.

The code for the method which takes a callback looks like this, notice we’re using the std::function to wrap our callback

void Update(
   std::vector<UpdateInfo*>& updates, 
   std::function<void(std::tstring&, std::tstring&)> callback)
{
   // does something and then calls the following 
   callback(item->source, item->destination)
}

To create the call we use

std::function<void(std::tstring&, std::tstring&)> f = 
   std::bind(&MyClass::NotifyUpdate, 
      this, 
      std::placeholders::_1, 
      std::placeholders::_2);

Update(f);

the _1, _2 are placeholders, allowing us to alter the values from the caller at a later time (i.e. from the Update method in this case). The std::bind method allows us to wrap a function ptr and an instance of the class containing the callback (the NotifyUpdate method).

C++ lambda’s in a little more depth

Lambda expressions appeared in C++ 11.

Let’s take a simple example. We want to create a lambda which takes an enum (of type UpdateFlag) and returns a LPTSTR (yes we’re in Visual C++ world) which we’ll use when we writing to cout.

We can create the lambda like this

auto lambda = [](UpdateFlag flag)
{
   switch (flag)
   {
      case UpdateFlag::Update:
         return _T("Update");
      case UpdateFlag::Delete:
         return _T("Delete");
      case UpdateFlag::Missing:
         return _T("Missing");
   }
};

if you prefer to not use the auto keyword we can use the functional code like this

std::function<LPCTSTR(UpdateFlag)> lambda = [](UpdateFlag flag)
{
// switch removed for brevity
};

I’m not quite sure where you’d need to use the std::function variation of this, but this is what it would look like.

Now to use our lambda, we’d simply have something like

std::cout << lamba(updateFlag);

We can also pass the lambda (without creating a variable to it) using the following

std::cout << [](UpdateFlag flag)
{
// switch removed for brevity
}(updateFlag);

Note: we need to pass the updateFlag in a parameter list after the lamba declaration.

The [] is an empty capture list, we could alter the previous samples (assuming a variable updateFlag is available within the scope of the lambda) by passing the updateFlag as part of the capture list, for example

auto updateFlag = UpdateFlag::Update;

auto lambda = [updateFlag]
{
   switch (updateFlag)
   {
      case UpdateFlag::Update:
         return _T("Update");
      case UpdateFlag::Delete:
         return _T("Delete");
      case UpdateFlag::Missing:
         return _T("Missing");
   }
};

Structuring the lamba

Let’s look at the format of the lamba…

The lamba syntax basically takes the form

  • [capture-list] (params) mutable(optional) constexpr(optional)(c++17) exception attribute -> ret { body }
  • [capture-list](params) -> ret { body }
  • [capture-list](params) { body }
  • [capture-list] { body }

The above is replicated from the Lambda expressions page.

The capture-list is a comma seperated list of zero or more captures, which takes or “captures” variables to be passed into the lambda.

The params are a standard list of parameters to pass into your lambda and the body is your actual code.

References

An excellent article on the subject of C++ 11 lambda’s can be found here.
The lambda specification can be found here.

Revisiting an old friend

Reminiscing

For many years (a long time ago in a galaxy far away) I was a C++ developer, but I haven’t done much in C++ for a while now, until recently…

I needed to revisit a C++ application I wrote (not quite so long ago) to make a few additions and at the same time I thought it worth reviewing the changes that have taken place in C++ in recent years. This post is primarily looking at some of the changes as part of C++ 11 that I’ve come across whilst updating my app. and whilst not comprehensive, should give a taste for “Modern C++”.

auto is to C++ what var is to C#

auto i = 1234;

This is resolved to the type at compile time (i.e. it’s not dynamic). The compiler simply resolves the type based upon the value on the right hand side of the assignment operator.

decltype

template<typename A, typename B>
auto f(A a, B b) -> decltype(a + b)
{
	return a + b;
}

We can also use it in a sort of dynamic typedef manner

decltype(123) v = 1;
// equivalent to 
int v = 1;

decltpye(123) declares the type as an int (as the type is taken from the argument passed in) then the value 1 is assigned to the variable.

for (each) loops known as range based loops in C++

The for loop (in a similar way to Java uses it) can be used as a foreach style loop. Although C++ calls this a range based loop. It only works on arrays or objects which have begin and end member functions (or initializer lists)

for(auto &it : myvector)
{   
}

// using initializer list

for(auto i : { 1, 2, 3})
{
}

nullptr takes over from NULL

The nullptr is a strongly typed keyword which can replace those NULL or 0 usages when setting or testing a variable to see whether it points at something or not.

if(errors == nullptr) 
{
}

Another benefit of the keyword being strongly typed is that in situations when we might have two methods (with the name overloaded) one taking and int, the second a pointer type, then the compiler can now correctly choose the pointer overload, for example

void f(int i)
{
}

void f(int* i)
{
}

f(NULL);    // calls f(int i)
f(nullptr); // calls f(int* i)

So obviously the use of the NULL suggests the developer wants to use f(int*), but this is ambiguous and both could be correct. In the case of Visual Studio f(int) is called when we use NULL.

Lamda’s as well

I’ve written a longer post on lambda’s which will be published after this post. However, here’s a taster showing a lamda used within the algorithm header’s std::for_each function

std::for_each(v.begin(), v.end(), [](int i)
{
   std::cout << i;
});

In this example, v is a vector of ints.

The lambda is denoted with the [] which captures variables from the calling code (in this case nothing is captured) and the rest is probably self-explanatory, we’ve created a lambda which takes and int and uses cout to write the value to the console.

Initializer lists

Like C# we can create lists using { } syntax, for example

std::array<int, 3> a = { 1, 2, 3 };
// or using a vector
std::vector<int> v = { 1, 2, 3 };

Sadly, Visual Studio 2015 doesn’t appear to fully support this syntax and allow us to easily intialize vectors etc. but CLion does. But thankfully Visual Studio 2017 does support this fully.

Note: Visual Studio 2015 accepts using std::vector v = { 3, (1,2,3) }; where the first number is the size of the vector.

Non-static member initializers

class FileData
{
public:
   long a {0};
   long b {1};
}

Upon creation of a FileData instance, a is initialized to 0 and b is initialized to 1.

Tuples

We can now create tuples by include the tuple header and creating a tuple using the std::make_tuple function, i.e.

auto t = std::make_tuple<int, std::string>(123, "Hello");

To get at each part of the tuple we can use either the get function or the tie function, like this

std::cout 
   << std::get<0>(t) 
   << std::get<1>(t) 
   << std::endl;

Note: the index goes in the template argument.

Or using tie

int a;
std::string b;

std::tie(a, b) = t;

std::cout 
   << a 
   << b 
   << std::endl;

std::thread, yes threads made easier

Okay, we’re not talking Task or async/await capabilities like C# but the std::thread class makes C++ threading that bit easier.

#include <thread>
#include <iostream>

void f(std::string s, int n) {
   for (int i = 0; i < n; i++)
      std::cout << s.c_str() << std::endl;
}
int main()
{
   std::thread thread1(f, "Hello", 10);
   std::thread thread2(f, "World", 3);
	
   thread1.join();
   thread2.join();

    return 0;
}

In this code we create a thread passing in the function and the arguments for the function, using join to wait until both threads have completed.

References

Modern C+ Features
Support For C++11/14/17 Features (Modern C++)

Anonymous fields in Go

Anonymous fields in Go structures allow us to shortcut dot notation as well as allow us to use compositions to add methods to a type.

Shortcutting the dot notation

For example if we have something like this

type A struct {
	X int
	Y int
}

type B struct {
	Z int
}

type C struct {
	AValue A
	BValue B
}

then to access the field X on AValue we’d write code like this

c := C {}
c.AValue.X = 1

Changing the C struct fields to anonymous (i.e. removing the field name) like this

type C struct {
	A
	B
}

allows us to reduce the use of the dot notation and access X on A as if it was a field within the C struct itself, i.e.

c := C {}
c.X = 1

Okay, but what if B struct now replaced the Z field name with X, i.e.

type A struct {
	X int
	Y int
}

type B struct {
	X int
}

We now have a situation where both A and B have the same field name, well we can still use anonymous fields, but we’re back to using more dot notation again to get around the obvious field name conflict, i.e.

c := C {}
c.A.X = 1
c.B.X = 2

Initializers do not support shortcutting

Unfortunately we not get the advantage of the anonymous fields with the initializer syntax, i.e. We must specify the A and B structs like this

c := C{ A : A{2, 4}, B : B { 12 }}

// or

c := C{ A : A{X : 2, Y : 4}, B : B { Z: 12 }}

// but this doesn't compile
c := C{ X : 2, Y : 4, Z : 12 }
// nor does this compile
c := C{ A.X : 2, A.Y = 3, B.Z : 12 }

Composition

More powerful than the synaptic sugar of embedded/anonymous fields, we can also use composition to increase the methods available on the struct C. For example let’s now add a method to the A type which allows us to move our X, Y point

func (a *A) Move(amount int) {
	a.X += amount
	a.Y += amount
}

Now we can call the method on the previously declared c variable like this

c.Move(10)

We can also create further methods via a composition pattern on type C if we want using empty types, let’s assume we have type D and extend the composition of type C

type D struct {}

type C struct {
	A
	B
	D
}

now we can add methods to D and ofcourse they’ll be available as part of C. So for example, maybe D acts as a receiver for methods that serialize data to JSON, now our C type will also appear to have those methods.