Is intersection casting possible in Kotlin? - casting

I have a method in Java like so:
public <T extends A & B> methodName(T arg, ...)
where A is a class and B is an interface.
In my kotlin class, I have another variable of type C, and I wish to achieve the following:
if (variable is A && variable is B) {
methodName(variable, ...)
} else {
// do something else
}
Is it possible to properly cast variable so that it may be used as an argument without errors?
Currently, the variable has a setter method, so smart casting isn't
available. However, I have also tested it with a local val and the
value is inferred to have type Any which doesn't help.

Kotlin does not support intersection types. This causes variable to be smart cast to Any, because that is the common ancestor of A and B.
However, Kotlin does support generic type constraints. You can use this to constrain a type parameter to one or more types. This can be used on both methods and classes. This is the syntax for functions (the equivalent of your methodName in Kotlin):
fun <T> methodName(arg: T)
where T : A,
T : B {
....
}
You can use this to get around your problem by creating a class which extends both A and B, and then delegates the implementation of these types to your object. Like this:
class AandB<T>(val t: T) : A by t, B by t
where T : A,
T : B
You can now call methodName by changing your if-test to check if it is a AandB<*>:
if (variable is AandB<*>) {
methodName(variable, ...)
}
You do need to wrap variable in a AandB somewhere though. I don't think you can do it if you don't have the type information for variable available anywhere.
Note: The AandB class does not implement hashCode, equals or toString. You could implement them to delegate to t's implementation.
Note 2: This only works if A and B are interfaces. You can not delegate to a class.

As #marstran points out, the when clause is how you specify multiple bounds. Here's a link to the documentation about upper-bounds. It's worth mentioning that you cannot have multiple bounds if one of your bounds is a generic type parameter.
You mentioned that you tried testing with smart-casting:
However, I have also tested it with a local val and the value is inferred to have type Any which doesn't help.
This is not the case for the current version of Kotlin (v1.4). You do not need to create an AandB class as you can use a val or local (captured) var to smart-cast to an intersection.
Here's an example (and runnable version):
interface I1 { fun one() = println("one") }
interface I2 { fun two() = println("two") }
class Both: I1, I2
val variable: Any = Both() // Starting with type 'Any'
if (variable is I1 && variable is I2) {
// Type is now '(I1 & I2)' Smart-cast from Any
variable.one()
variable.two()
}
Here's a link to more discussion and runnable example of Kotlin intersection types as of v1.4

Related

Is it possible to parameterize a generic with a type that is itself generic? [duplicate]

Is it possible to do something like this in Rust?
trait Foo<T> {}
struct A;
struct B;
struct Bar<T: Foo> {
a: T<A>,
b: T<B>
}
I know I could just use two parameters for Bar, but I think there has to be a better way to do this.
I want to implement a Graph structure. As I can't just bind the nodes and edges to their parents lifetime, I want to have something like Rc. However, sometimes one may need a Graph with access from multiple threads. So I'd have to have both an implementation with Rc and Arc.
That's what Foo is good for: I implement Foo for both Rc and Arc (Foo would require Deref) and I use a parameter T bound to Foo. That's how I wanted to have one struct for single thread and multi thread usage.
⇒ This is currently impossible to express in Rust's type system ☹
Fortunately, it will be possible in the future thanks to "Generic Associated Types" as proposed in this RFC. You can track the status of implementation and stabilization in the corresponding tracking issue.
The important term here is "HKT" (higher kinded types). It's a feature of a type system which is not yet implemented in Rust. Haskell offers HKTs. In the C++ world HKTs are known as "template templates". The generic associated types mentioned above are also a form of HKTs.
But what are HKTs, really?
Let's start slowly: what is a simple type as we know it? Let's list some types: i32, bool, String. These are all types... you can have a value (variable) of these types. What about Vec<i32>? It's also a simple type! You can have a variable of type Vec<i32>, no problem!
We want to group these types together; we call this categorisation a "kind of a type". If we want to talk in a very abstract way (about types of types) we choose other words, kind in this case. There is even a notation for kinds of types. For our simple types from above, we say: the kind of those types is
*
Yes, just a star, very easy. The notation makes more sense later!
Let's search for types that are of a different kind than our simple types. Mutex<HashMap<Vec<i32>, String>>? Nope, it's fairly complex maybe, but it's still of kind * and we still can have a variable of that type.
What about Vec? Yes, we omitted the angle-brackets. Yes, this is indeed another kind of type! Can we have a variable of type Vec? No! A vector of what?!
This kind is donated as:
* -> *
This just says: give me a normal type (*) and I will return a normal type! Give a normal type i32 to this thing (Vec) and it will return a normal type Vec<i32>! It's also called a type constructor, because it is used to construct types. We can even go further:
* -> * -> *
This is a bit strange, because it has to do with currying and reads odd for a non-Haskell programmer. But it means: give me two types and I will return a type. Let's think about an example... Result! The Result type constructor will return a concrete type Result<A, B> after you provided two concrete types A and B.
The term higher kinded types just refers to all kinds of types which are not *, which are type constructors.
In your example
When you write struct Bar<T: Foo> you want T to be of the kind * -> *, meaning: you can give one type to T and receive a simple type. But as I said, this is not yet expressible in Rust. To use a similar syntax, one might imagine that this could work in the future:
// This does NOT WORK!
struct Bar<for<U> T> where T<U>: Foo {
a: T<A>,
b: T<B>,
}
The for<> syntax is borrowed from "higher-ranked trait bounds" (HRTB), which can be used today for abstracting over lifetimes (most commonly used with closures).
Links
In case you want to read more about this topic, here are some links:
Niko Matsakis' great series of blog posts discussing one possible solution (associated type constructors) to the HKT problem
The RFC proposing generic associated types (just a less scary name for "associated type constructors")
HRTB explanation
Bonus: the solution to your problem in case associated type constructors will be implemented (I think, as there is no way to test)!
We have to take a detour in our implementation since the RFC wouldn't allow to pass Rc as a type parameter directly. It doesn't introduce HKTs directly, so to speak. But as Niko argues in his blog post, we can have the same flexibility and power as HKTs with associated type constructors by using so called "family traits".
/// This trait will be implemented for marker types, which serve as
/// kind of a proxy to get the real type.
trait RefCountedFamily {
/// An associated type constructor. `Ptr` is a type constructor, because
/// it is generic over another type (kind * -> *).
type Ptr<T>;
}
struct RcFamily;
impl RefCountedFamily for RcFamily {
/// In this implementation we say that the type constructor to construct
/// the pointer type is `Rc`.
type Ptr<T> = Rc<T>;
}
struct ArcFamily;
impl RefCountedFamily for ArcFamily {
type Ptr<T> = Arc<T>;
}
struct Graph<P: RefCountedFamily> {
// Here we use the type constructor to build our types
nodes: P::Ptr<Node>,
edges: P::Ptr<Edge>,
}
// Using the type is a bit awkward though:
type MultiThreadedGraph = Graph<ArcFamily>;
For more information, you should really read Niko's blog posts. Difficult topics explained well enough, that even I can understand them more or less!
EDIT: I just noticed that Niko actually used the Arc/Rc example in his blog post! I totally forgot that and thought of the code above myself... but maybe my subconscious still remembered, as I choose a few names exactly as Niko did. Anyway, here is his (probably way better) take on the issue.
In a way Rust does have what looks a lot like HKT (see Lukas's answer for a good description of what they are), though with some arguably awkward syntax.
First, you need to define the interface for the pointer type you want, which can be done using a generic trait. For example:
trait SharedPointer<T>: Clone {
fn new(v: T) -> Self;
// more, eg: fn get(&self) -> &T;
}
Plus a generic trait which defines an associated type which is the type you really want, which must implement your interface:
trait Param<T> {
type Pointer: SharedPointer<T>;
}
Next, we implement that interface for the types we're interested in:
impl<T> SharedPointer<T> for Rc<T> {
fn new(v: T) -> Self {
Rc::new(v)
}
}
impl<T> SharedPointer<T> for Arc<T> {
fn new(v: T) -> Self {
Arc::new(v)
}
}
And define some dummy types which implement the Param trait above. This is the key part; we can have one type (RcParam) which implements Param<T> for any T, including being able to supply a type, which means we're simulating a higher-kinded type.
struct RcParam;
struct ArcParam;
impl<T> Param<T> for RcParam {
type Pointer = Rc<T>;
}
impl<T> Param<T> for ArcParam {
type Pointer = Arc<T>;
}
And finally we can use it:
struct A;
struct B;
struct Foo<P: Param<A> + Param<B>> {
a: <P as Param<A>>::Pointer,
b: <P as Param<B>>::Pointer,
}
impl<P: Param<A> + Param<B>> Foo<P> {
fn new(a: A, b: B) -> Foo<P> {
Foo {
a: <P as Param<A>>::Pointer::new(a),
b: <P as Param<B>>::Pointer::new(b),
}
}
}
fn main() {
// Look ma, we're using a generic smart pointer type!
let foo = Foo::<RcParam>::new(A, B);
let afoo = Foo::<ArcParam>::new(A, B);
}
Playground

C++ Dynamic Dispatch Function

I'm trying to create an overloaded function that will be called with the dynamic type of an object. I try to do this without interfering with the actual class structure underneath, as I don't have direct access (i.e. I cannot add virtual methods, etc.)
As a concrete example, let's think of an AST class structure that looks somewhat like this:
class ASTNode {}; // this one is fully abstract; i.e. there's a virtual void method() = 0;
class Assignment : ASTNode {};
class Expression : ASTNode {};
class StringExpr : Expression {};
class MathExpr : Expression {};
I want to write a function act that will take an instance of ASTNode as parameter and, depending on its actual dynamic type do something different.
The call will be something like this
std::shared_ptr<ASTNode> parsedAST = get_a_parsed_ASTNode(); // ... received from some parser or library
act(parsedAST);
Then, I want to act, depending on the dynamic type of the ASTNode.
void act(std::shared_ptr<MathExpr> expr)
{
// Do something with Math expressions, e.g. evaluate their value
};
void act(std::shared_ptr<StringExpr> expr)
{
// Do something with String expressions, e.g. write their value to the log
};
void act(std::shared_ptr<Expression> expr)
{
// do something with other types of expressions (e.g. Boolean expressions)
};
Currently though, I cannot call since they dynamic type will be maybe not the ``most concrete type''. Instead, I have to manually create a dispatcher manually as follows, but the method is a bit silly in my opinion, since it does literally nothing else but dispatch.
void act(std::shared_ptr<ASTNode> node_ptr)
{
if(std::shared_ptr<MathExpr> derived_ptr = std::dynamic_pointer_cast<MathExpr>(node_ptr))
{
act(derived_ptr);
}
else if(std::shared_ptr<StringExpr> derived_ptr = std::dynamic_pointer_cast<StringExpr>(node_ptr))
{
act(derived_ptr);
}
else if(std::shared_ptr<Expression> derived_ptr = std::dynamic_pointer_cast<Expression>(node_ptr))
{
// do something with generic expressions. Make sure that this is AFTER the more concrete if casts
}
else if( ... ) // more of this
{
}
// more else if
else
{
// default action or raise invalid argument exception or so...
}
};
This is especially annoying & error-prone since my class hierarchy has many (> 20) different concrete classes that can be instantiated. Also, I have various act-functions, and when I refactor things (e.g. add an act for an additional type), I have to make sure to pay attention to the correct order of if(dynamic_pointer_cast) within the dispatcher.
Also it's not that stable, since a change in the underlying class hierarchy will require me to change every dispatcher directly, rather than just the specific act functions.
Is there a better / smarter solution? Evidently I'd appreciate "native" solutions, but I'm willing to consider libraries too.
Never encountered such problem myself, but can think of the following solution.
Create you hierarchy that mimics original hierarchy, has virtual act, the base has base pointer, and each cast it to the corresponding derived pointer.
Now, to create the needed wrapper, you don't need properly ordered dynamic_cast, dispach on typeid string. So your dispatch is a map from string to wrapper factory.
Sure you need RTTI for typeid string, but you would need it for dynamic_cast as well.

Kotlin seemingly recursive template type that compiles

Doing code review at work and came across a use of template types I've not seen before. Upon first glance it looked like the code shouldn't compile as the definition seemed recursive. I've boiled it down to the most simple verifiable example:
interface Bar<T>
interface Foo<T: Bar<T>> // Surely this is recursive?
My understanding of how template types work is:
interface Foo<T> - a Foo of T, no constraints
interface Foo<T : Bar> - a Foo of T, where T is constrained to a Bar
Assuming what I said above is true, then this doesn't make sense to me:
interface Bar<T> - a Bar of T, no constraint on T
interface Foo<T: Bar<T>> - a Foo of T, where T is constrained to a Bar<T>
Uh oh, how can T be defined in terms of Bar<T>?.
We know T is a Bar<T>, so if we substitute the T in Bar<T>, well it's a Bar<Bar<T>>.
we still haven't resolved T for Bar... For sake of argument, let's substitute T again. Now we have T being a Bar<Bar<Bar<T>>>. Surely this goes into infinity no?
CRTP (recursively bounded quantification) is a well-known design idiom which is often used (among other things) to provide generic code with some sort of a "self" type.
Here's a practical example of recursive generics.
Say you have a function that operates on a set of comparable values.
fun <T> findMax(collection: Collection<T>): T?
Ideally, we would like to constrain this function to only operate on collections of Comparable values:
fun <T> findMax(collection: Collection<Comparable<T>>): Comparable<T>?
And that's all. Right?
While this will work, you'd need a cast on the return value for it to do anything useful, since it returns a Comparable<T> rather than a T.
Now let's say we try:
fun <T : Comparable<T>> findMax(collection: Collection<T>): T?
Much better. This ensures:
T is Comparable
and more importantly, T is comparable to itself
The same applies to classes and inheritance.
interface SelfReturner<T : SelfReturner<T>> {
fun getSelf(): T
}
class A : SelfReturner<A> {
override fun getSelf(): A // <--
}
This works fine thanks to return type covariance, because A is a SelfReturner<A>.
This is commonly used to allow a class to "know" its own type, though it's important to keep in mind that it is not foolproof:
class Impostor : SelfReturner<A> {
override fun getSelf(): A // <-- oops!
}
While you're right about the apparent recursiveness of these generics, because one could indeed instead write
fun <T : Comparable<Comparable<Comparable<...>>>> findMax(collection: Collection<T>): T?
this doesn't go on forever because the condition is generally satisfied after a single level of recursion (say we use String, for example. It is a Comparable<String>, and that's all the compiler needs to check.)
Note that unlike e.g. C++, Kotlin does not use templates. Generic type information is only used by the compiler to ensure code correctness, and is not preserved* (see type erasure) in the compiled code.
Whereas template instantiation will result in the creation of a new and completely separate type, generic types are all erased to the same (non-generic) class at runtime.
* This isn't completely true; some generic type information is available to reflection, which is why type tokens work, but it's only available in limited circumstances.
Fun fact: Wikipedia claims that this was discovered by accident,
by Jan Falkin, who accidentally derived a base class from a derived class
so it appears to have been just as confusing even to those who came up with the concept.
Yes, there's no citation, but let's not ruin the magic. :)
Recursive Type Bound
The pattern you are referring to is called a recursive type bound in the JVM world. In generics, when a reference type has a type parameter that is bounded by the reference type itself, then that type parameter is said to have a recursive type bound.
For example, in the generic type Fruit<T extends Fruit<T>>, Fruit is the reference type, its type parameter T is bounded by the Fruit itself, so, the type parameter T has a recursive type bound Fruit<T>.
Let's solve a simple problem to understand this concept step by step.
Problem
Assume that we have to sort the fruits by their sizes. And we are told that we can only compare fruits of the same types. For example, we can't compare apples with oranges (pun intended).
So, we create a simple type hierarchy like following,
Fruit.kt
interface Fruit {
val size: Int
}
Apple.kt
class Apple(override val size: Int) : Fruit, Comparable<Apple> {
override operator fun compareTo(other: Apple): Int {
return size.compareTo(other.size)
}
}
Orange.kt
class Orange(override val size: Int) : Fruit, Comparable<Orange> {
override operator fun compareTo(other: Orange): Int {
return size.compareTo(other.size)
}
}
Test
fun main() {
val apple1 = Apple(1)
val apple2 = Apple(2)
println(apple1 > apple2) // No error
val orange1 = Orange(1)
val orange2 = Orange(2)
println(orange1 < orange2) // No error
println(apple1 < orange1) // Error: different types
}
Solution
In this code, we are able to achieve our objective of being able to compare the same types, that is, apples with apples and oranges with oranges. When we compare an apple with an orange we get an error which is what we want.
Problem
The problem here is that the code for implementing the compareTo() method is duplicated for Apple and Orange class. And will be duplicated more in all the classes that we extend from the Fruit when we create new fruits in the future. The amount of repeated code in our example is less but in the real world, the repeated code can be of hundreds of lines in each class.
Moving the Repeated Code to Interface
Fruit.kt
interface Fruit : Comparable<Fruit> {
val size: Int
override operator fun compareTo(other: Fruit): Int {
return size.compareTo(other.size)
}
}
Apple.kt
class Apple(override val size: Int) : Fruit
Orange.kt
class Orange(override val size: Int) : Fruit
Solution
In this step, we get rid of the repeated code of compareTo() method by moving it to the interface. Our extended classes Apple and Orange are no longer polluted with common code.
Problem
Now the problem is that we are now able to compare different types, comparing apples to oranges no longer gives us an error:
println(apple1 < orange1) // No error
Introducing a Type Parameter
Fruit.kt
interface Fruit<T> : Comparable<T> {
val size: Int
override operator fun compareTo(other: T): Int {
return size.compareTo(other.size) // Error: size not available.
}
}
Apple.kt
class Apple(override val size: Int) : Fruit<Apple>
Orange.kt
class Orange(override val size: Int) : Fruit<Orange>
Solution
To restrict the comparison of different types, we introduce a type parameter T. So that the comparable Fruit<Apple> cannot be compared to comparable Fruit<Orange>. Note our Apple and Orange classes; they now inherit from the types Fruit<Apple> and Fruit<Orange> respectively. Now if we try to compare different types, the IDE shows an error, our desired behaviour:
println(apple1 < orange1) // Error: different types
Problem
But in this step, our Fruit class doesn't compile. The size property of T is unknown to the compiler. This is because the type parameter T of our
Fruit class doesn't have any bound. So, the T could be any class, it is not possible that every class in the world would have a size property. So the compiler is right in not recognizing the size property of T.
Introducing a Recursive Type Bound
Fruit.kt
interface Fruit<T : Fruit<T>> : Comparable<T> {
val size: Int
override operator fun compareTo(other: T): Int {
return size.compareTo(other.size)
}
}
Apple.kt
class Apple(override val size: Int) : Fruit<Apple>
Orange.kt
class Orange(override val size: Int) : Fruit<Orange>
Final Solution
So, we tell the compiler that our T is a subtype of Fruit. In other words, we specify the upper bound T extends Fruit<T>. This makes sure that only subtypes of Fruit are allowed as type arguments. Now the compiler knows that the size property can be found in the subtype of Fruit class (Apple, Orange etc.) because the Comparable<T> also receives our type(Fruit<T>) that contains the size property.
This allows us to get rid of the repeated code of compareTo() method and also allows us to compare the fruits of the same types, apples with apples and oranges with oranges.
More About Recursive Type Bounds
A recursive type is one that includes a function that uses that type itself as a type for some argument or its return value. In our example, compareTo(other: T) is the function of the recursive type that takes the same recursive type as an argument.
Caveat
The caveat in this pattern is that the compiler doesn’t prevent us from creating a class with a type argument of other subtype:
class Orange(override val size: Int) : Fruit<Orange>
class Apple(override val size: Int) : Fruit<Orange> // No error
Note in the Apple class above, by mistake we passed Orange instead of Apple itself as a type argument. This results in the compareTo(other: T) method to take Orange instead of Apple.
Now we no longer get error while comparing different types and suddenly can't compare apples with apples:
println(apple1 < orange1) // No error
println(apple1 > apple2) // Error
So, the developer needs to be careful while extending the classes.
Infinite Recursion Not Possible
The declaration Fruit<T extends Fruit<T>> makes sure that only the subtypes of type Fruit<T> are allowed by the compiler. Fruit<Fruit<T>> or Fruit<Fruit<Fruit<T>>> and so on are not the subtypes of Fruit<T>, in other words, they are not within bound.
For example, if we use the declaration in the following manner:
class Orange(override val size: Int) : Fruit<Fruit<Orange>>
The compiler will give error: Type argument is not within its bound
There is no imaginable use case for Fruit<Fruit>, so the compiler doesn't allow that either. Only the first level is allowed, that is, Fruit<Apple>, Fruit<Orange> etc.
These two things together prevent the infinite recursion.
That's it! Hope that helps.

cannot use MockDaoInterface literal (type MockDaoInterface) as type s3.DaoInterface in assignment: MockDaoInterface does not implement s3.DaoInterface [duplicate]

There are already several Q&As on this "X does not implement Y (... method has a pointer receiver)" thing, but to me, they seems to be talking about different things, and not applying to my specific case.
So, instead of making the question very specific, I'm making it broad and abstract -- Seems like there are several different cases that can make this error happen, can someone summary it up please?
I.e., how to avoid the problem, and if it occurs, what are the possibilities? Thx.
This compile-time error arises when you try to assign or pass (or convert) a concrete type to an interface type; and the type itself does not implement the interface, only a pointer to the type.
Short summary: An assignment to a variable of interface type is valid if the value being assigned implements the interface it is assigned to. It implements it if its method set is a superset of the interface. The method set of pointer types includes methods with both pointer and non-pointer receiver. The method set of non-pointer types only includes methods with non-pointer receiver.
Let's see an example:
type Stringer interface {
String() string
}
type MyType struct {
value string
}
func (m *MyType) String() string { return m.value }
The Stringer interface type has one method only: String(). Any value that is stored in an interface value Stringer must have this method. We also created a MyType, and we created a method MyType.String() with pointer receiver. This means the String() method is in the method set of the *MyType type, but not in that of MyType.
When we attempt to assign a value of MyType to a variable of type Stringer, we get the error in question:
m := MyType{value: "something"}
var s Stringer
s = m // cannot use m (type MyType) as type Stringer in assignment:
// MyType does not implement Stringer (String method has pointer receiver)
But everything is ok if we try to assign a value of type *MyType to Stringer:
s = &m
fmt.Println(s)
And we get the expected outcome (try it on the Go Playground):
something
So the requirements to get this compile-time error:
A value of non-pointer concrete type being assigned (or passed or converted)
An interface type being assigned to (or passed to, or converted to)
The concrete type has the required method of the interface, but with a pointer receiver
Possibilities to resolve the issue:
A pointer to the value must be used, whose method set will include the method with the pointer receiver
Or the receiver type must be changed to non-pointer, so the method set of the non-pointer concrete type will also contain the method (and thus satisfy the interface). This may or may not be viable, as if the method has to modify the value, a non-pointer receiver is not an option.
Structs and embedding
When using structs and embedding, often it's not "you" that implement an interface (provide a method implementation), but a type you embed in your struct. Like in this example:
type MyType2 struct {
MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: m}
var s Stringer
s = m2 // Compile-time error again
Again, compile-time error, because the method set of MyType2 does not contain the String() method of the embedded MyType, only the method set of *MyType2, so the following works (try it on the Go Playground):
var s Stringer
s = &m2
We can also make it work, if we embed *MyType and using only a non-pointer MyType2 (try it on the Go Playground):
type MyType2 struct {
*MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: &m}
var s Stringer
s = m2
Also, whatever we embed (either MyType or *MyType), if we use a pointer *MyType2, it will always work (try it on the Go Playground):
type MyType2 struct {
*MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: &m}
var s Stringer
s = &m2
Relevant section from the spec (from section Struct types):
Given a struct type S and a type named T, promoted methods are included in the method set of the struct as follows:
If S contains an anonymous field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.
If S contains an anonymous field *T, the method sets of S and *S both include promoted methods with receiver T or *T.
So in other words: if we embed a non-pointer type, the method set of the non-pointer embedder only gets the methods with non-pointer receivers (from the embedded type).
If we embed a pointer type, the method set of the non-pointer embedder gets methods with both pointer and non-pointer receivers (from the embedded type).
If we use a pointer value to the embedder, regardless of whether the embedded type is pointer or not, the method set of the pointer to the embedder always gets methods with both the pointer and non-pointer receivers (from the embedded type).
Note:
There is a very similar case, namely when you have an interface value which wraps a value of MyType, and you try to type assert another interface value from it, Stringer. In this case the assertion will not hold for the reasons described above, but we get a slightly different runtime-error:
m := MyType{value: "something"}
var i interface{} = m
fmt.Println(i.(Stringer))
Runtime panic (try it on the Go Playground):
panic: interface conversion: main.MyType is not main.Stringer:
missing method String
Attempting to convert instead of type assert, we get the compile-time error we're talking about:
m := MyType{value: "something"}
fmt.Println(Stringer(m))
To keep it short and simple, let say you have a Loader interface and a WebLoader that implements this interface.
package main
import "fmt"
// Loader defines a content loader
type Loader interface {
load(src string) string
}
// WebLoader is a web content loader
type WebLoader struct{}
// load loads the content of a page
func (w *WebLoader) load(src string) string {
return fmt.Sprintf("I loaded this page %s", src)
}
func main() {
webLoader := WebLoader{}
loadContent(webLoader)
}
func loadContent(loader Loader) {
loader.load("google.com")
}
The above code will give you this compile time error
./main.go:20:13: cannot use webLoader (type WebLoader) as type Loader
in argument to loadContent:
WebLoader does not implement Loader (Load method has pointer receiver)
To fix it you only need to change webLoader := WebLoader{} to following:
webLoader := &WebLoader{}
Why this will fix the issue? Because you defined this function func (w *WebLoader) Load to accept a pointer receiver. For more explanation please read #icza and #karora answers
Another case when I have seen this kind of thing happening is if I want to create an interface where some methods will modify an internal value and others will not.
type GetterSetter interface {
GetVal() int
SetVal(x int) int
}
Something that then implements this interface could be like:
type MyTypeA struct {
a int
}
func (m MyTypeA) GetVal() int {
return a
}
func (m *MyTypeA) SetVal(newVal int) int {
int oldVal = m.a
m.a = newVal
return oldVal
}
So the implementing type will likely have some methods which are pointer receivers and some which are not and since I have quite a variety of these various things that are GetterSetters I'd like to check in my tests that they are all doing the expected.
If I were to do something like this:
myTypeInstance := MyType{ 7 }
... maybe some code doing other stuff ...
var f interface{} = myTypeInstance
_, ok := f.(GetterSetter)
if !ok {
t.Fail()
}
Then I won't get the aforementioned "X does not implement Y (Z method has pointer receiver)" error (since it is a compile-time error) but I will have a bad day chasing down exactly why my test is failing...
Instead I have to make sure I do the type check using a pointer, such as:
var f interface{} = new(&MyTypeA)
...
Or:
myTypeInstance := MyType{ 7 }
var f interface{} = &myTypeInstance
...
Then all is happy with the tests!
But wait! In my code, perhaps I have methods which accept a GetterSetter somewhere:
func SomeStuff(g GetterSetter, x int) int {
if x > 10 {
return g.GetVal() + 1
}
return g.GetVal()
}
If I call these methods from inside another type method, this will generate the error:
func (m MyTypeA) OtherThing(x int) {
SomeStuff(m, x)
}
Either of the following calls will work:
func (m *MyTypeA) OtherThing(x int) {
SomeStuff(m, x)
}
func (m MyTypeA) OtherThing(x int) {
SomeStuff(&m, x)
}
Extend from above answers (Thanks for all of your answers)
I think it would be more instinctive to show all the methods of pointer / non pointer struct.
Here is the playground code.
https://play.golang.org/p/jkYrqF4KyIf
To summarize all the example.
Pointer struct type would include all non pointer / pointer receiver methods
Non pointer struct type would only include non pointer receiver methods.
For embedded struct
non pointer outer struct + non pointer embedded struct => only non pointer receiver methods.
non pointer outer struct + pointer embedded struct / pointer outer struct + non pointer embedded struct / pointer outer struct + pointer embedded struct => all embedded methods

Syntax clarification

I was browsing some of Ubuntu's Mir examples and i stumbled upon code that i couldn't understand.
struct DemoServerConfiguration : mir::DefaultServerConfiguration
{
What is going on here ": mir::DefaultServerConfiguration"?
Inside that struct there's this
std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
{
return shell_placement_strategy(
[this]
{
return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
});
}
Same story here, i don't understand the syntax the unclear parts are:
<msh::PlacementStrategy> the_shell_placement_strategy()
and
return shell_placement_strategy(
[this]
{
Inside the same struct again
std::initializer_list<std::shared_ptr<mi::EventFilter> const> the_event_filters() override
{
return filter_list;
}
Why the multiple <> <> <> nested? Why the the_event_filters() there?
And the last piece
mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
{
code
});
Unclear part
(config, [&config, &wm](mir::DisplayServer&)
);
First example
That's simply a case of inheriting from an internal type:
class C
{
public:
class Internal
{
};
};
class D : public C::Internal
{
// D derives from Internal class, which is a member of C class
};
The :: is an operator of scope resolution. The expression A::B means: "B, which is a member of A". :: works for classes, structures and namespaces.
Second example
That's a little bit more complicated.
std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
{
return shell_placement_strategy(
[this]
{
return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
});
}
Let's break it to parts.
std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
This is a function / method the_shell_placement_strategy, which returns a result of type std::shared_ptr (generic class parametrized with msh::PlacementStrategy - see previous point).
return shell_placement_strategy(
It returns result of calling the shell_placement_strategy...
[this]
{
return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
}
...which takes a lambda (nameless function) as a parameter. That nameless function wants to have access to this (thus [this]) and returns result of call to generic function std::make_shared, parametrized with me::FulscreenPlacementStrategy and called with parameter being a result of calling the_display() method / function.
You may read about lambdas elsewhere, but I'll include a short explanation for reference:
[access-specification](parameters){ body }
Where:
access-specification defines the relation between lambda and local variables. For example, [a] means, that lambda will have access to local variable a by value; [&a] - the same, but by reference; [&] - lambda will have access to all local variables by reference and so on.
parameters - regular definition of function parameters
body - regular body of lambda.
The lambda notation is a part of C++11 standard.
Last example
You now should be able to interpret this example:
mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
{
code
});
Thats:
A call to run_mir method (or function), which is a part of mir class (or namespace);
With two parameters: config and a function, which accepts two parameters;
config is passed as first parameter;
A lambda is passed by the second parameter.
Now the lambda:
It wants to access by reference two local variables: config and wm
It accepts one parameter of type mir::DisplayServer& (there's no name for this parameter, so it seems, that it does not actually use it
It does <code> :)
First case, it is private inheritance. DemoServerConfiguration is derived from mir::DefaultServerConfiguration, where mir is probably a namespace (but could also be a class that declares the inner class DefaultServerConfiguration.
Second case, you are looking at lambda expression definition. You can read some introduction here.
Finally, the initializer lists are actually another feature introduced in C++11 standard (not yet supported by most of the compilers, AFAIK). Some introduction about them here.
mir::DefaultServerConfiguration
Here mir could be a namespace or a class inside which DefaultServerConfiguration is defined. So for example, it could be this:
namespace mir
{
class DefaultServerConfiguration
{
/*...*/
};
}
Or this,
class mir
{
public:
class DefaultServerConfiguration
{
/*...*/
};
}
In both cases, you could access the class DefaultServerConfiguration as:
mir::DefaultServerConfiguration
The same is true for other cases.
struct DemoServerConfiguration : mir::DefaultServerConfiguration
{
Here DemoServerConfiguration is a class deriving from mir::DefaultServerConfiguration. Make sense?
You also notice this in case of std::make_shared. Here std is a namespace defined by C++ Standard Library inside which the library defines make_shared function template.
Hope that helps.