What is difference between "as" and "is" operator in Kotlin? - casting

In Java, I can write code like:
void cast(A a) {
if(a instanceof Person) {
Person p = (Person) a;
}
}
In Kotlin, what should I do?
Use as operator or is operator?

is X is the equivalent of instanceof X
foo as X is the equivalent of ((X) foo)
Additionally, Kotlin performs smart casting where possible, so no additional cast needed after you check the type using is:
open class Person : A() {
val foo: Int = 42
}
open class A
and then:
if (p is Person) {
println(p.foo) // look, no cast needed to access `foo`
}

is is type checking. But Kotlin has smart cast which means you can use a like Person after type check.
if(a is Person) {
// a is now treated as Person
}
as is type casting. However, as is not recommended because it does not guarantee run-time safety. (You may pass a wrong object which cannot be detected at compiled time.)
Kotlin has a safe cast as?. If it cannot be casted, it will return null instead.
val p = a as? Person
p?.foo()

"Kotlin in action" by Dmitry Jemerov and Svetlana Isakova has a good example of as and is:

is - To check if an object is of a certain type
Example:
if (obj is String) {
print(obj.length)
}
as - To cast an object to a potential parent type
Example:
val x: String = y as String
val x: String? = y as String?
val x: String? = y as? String
Reference: https://kotlinlang.org/docs/reference/typecasts.html

As per Kotline official documents
Usually, the cast operator throws an exception if the cast is not possible. Thus, we call it unsafe. The unsafe cast in Kotlin is done by the infix operator as
val x: String = y as String
Note that null cannot be cast to String as this type is not nullable, i.e. if y is null, the code above throws an exception. In order to match Java cast semantics we have to have nullable type at cast right hand side, like:
val x: String? = y as String?
So here use is instead of as
fun cast(a: A) {
if (a is Person) {
val p = a as Person
}
}

as is used for explicit type casting
val p = a as Person;
is is exactly the same as instanceof in Java. Which is used to check if an object is an instance of a class
if(a is Person) {
// a is an instance of Person
}
You can also used !is as is it not an object of a class
fun cast(a: A) {
if(a is Person) {
val p = a as Person;
}
}

is Operator is checking datatype
but as is for casting to some type for example casting Int to String

so
if(a is Person){
a as Person
}else{
null
}
equivalent
a as? Person
Is this answer?

you can use is operator
fun cast(a:A){
if (a is Person){
var person = a
}
}

Related

Is there a way of creating an std::optional<> out of a nullable argument?

Languages such as Scala and Java have had for quite some time some sort of optional type. In both, there seems to be a constructor method allowing one to either pass in an object O or a null value. The first constructs an optional value with a copy of O inside it, the second, an empty option.
From what I can gather, such a thing is not possible with std::optional<>(v) and std::make_optional<>(v), as both throw a runtime exception when called with a nullptr argument.
Is there any other constructor function allowing me to do this in the standard library?
Thanks
Since you didn't showed any code example, I will assume the following:
You have a function called f
The function f takes a potentially null int* as parameter (the nullable argument)
The function f returns a std::optional<int>
I will assume you have a similar function body in your codebase
Edit your question to add a more relevant examples if my assumptions are wrong.
So to recap the code example:
auto f(int* ptr) -> std::optional<int> {
return std::optional<int>{*ptr};
}
The problem don't lie in std::optional and its contructors, but in the fact that you dereference a null pointer. This happen before any constructor call. At this point, you're already in UB land, you cannot infer behaviour after this happens.
The fix is to check the pointer before constructing the optional value:
auto f(int* ptr) -> std::optional<int> {
return ptr ? std::optional<int>{*ptr} : std::nullopt;
}
Now, the int you send to the std::optional constructor is always valid assuming ptr is valid or null, and you return an empty optional if not.
An important property of std::optional is to not involve dynamic allocations. The object is (optionally) stored directly in the std::optional.
A std::optional<T> cannot hold a nullptr when T cannot have a nullptr value.
A std::optional can be constructed empty by calling the appropriate constructor:
// either
std::optional<int> x; // does not contain an int
// or
std::optional<int> y{std::nullopt}; // does not contain an int
Maybe you want std::nullopt, it signifies that optional doesn't hold value, in other words optional + nullopt is exactly what null means in other lanugages. In other words std::optional + std::nullopt inroduce natural sence of null into C++, same as in other languages.
Through std::nullopt you can control optional arguments in the function, like I did below for add() function.
You just check if (optional_value) to find out if it holds value, which is same as if (optional_value.has_value()). See doc here.
Also you can use .value_or(default) to return value or default, it is same as saying var or default or var if var is not None else default in Python for None-able argument.
You can also get value of optional just by *optional_value dereference, same like pointer. Doc here.
See all 4 possibilities of using nullable optional in implementation of add() function, it has 4 ways of doing same thing, choose which is better for you.
Try it online!
#include <optional>
#include <iostream>
int add(int x, std::optional<int> y = std::nullopt) {
return x + y.value_or(5);
// also possible to do same like this
return x + (y ? y.value() : 5);
// or same as
return x + (y ? *y : 5);
// or same as
if (y)
return x + *y;
else
return x + 5;
}
int main() {
std::cout << add(3) << std::endl;
std::cout << add(3, std::nullopt) << std::endl;
std::cout << add(3, 7) << std::endl;
}
Output:
8
8
10
In other words if you want any variable to hold both value of some type and also null, then just wrap it into std::optional, and use std::nullopt to signify null, like in following example:
SomeClass obj; // non-nullable, can't be null
std::optional<SomeClass> obj2; // almost same as above but now is nullable
obj2 = obj; // you can naturally assign value of object
obj2 = std::nullopt; // this way you set variable to null
obj = *obj2; // this way you get value of object by using * dereference
obj = obj2.value(); // same as above instead of *
obj = obj2 ? *obj2 : default_value; // this way you check if obj2 is null, if not then get it's value through *, otherwise return default
obj = obj2.value_or(default_value); // same as last line above
if (obj2) DoSomething(); // checks if object is not null
if (obj2.has_value()) DoSomething(); // same as above
See all docs about std::optional.

C++: how to return object's set state when used as logical value

I have some class that can be set or not:
Class obj;
I want its value, when used in logic, to return whether or not it's set:
if ( obj )
obj.Clear();
if ( !obj )
obj.Set( "foo" );
I thought of adding in an implicit conversion to bool, but I wonder if int would be necessary or whether there's a better way to go about this.
You can define a bool operator, as follows
#include <iostream>
struct Object{
bool state;
explicit operator bool()const{
return state;
}
};
int main(){
Object o1;
Object o2;
o1.state = false;
o2.state = true;
std::cout << "\no1 state is " << (o1? "true": "false");
std::cout << "\no2 state is " << (!o2? "false": "true");
}
The output is
o1 state is false
o2 state is true
Live
You can use std::optional or std::shared_ptr.
Example 1:
std::optional<Object> obj = Object();
if (obj) obj->useIt();
obj.reset();
if (obj) ... ;
Example 2
std::shared_ptr<Object> obj = new Object();
if (obj) obj->useIt();
obj.reset();
if (obj) ... ;
You should represent optional values using std::optional. This is self documenting, other programmers know what they are about, and you avoid checking for invariant states of your own class (reduce complexity). It also uses STL conventions for value wrappers (same as iterators, smart pointers, etc.).
If you don't want to or simply can't use it, look at it's implementation and follow the same rules:
implement a bool-conversion-operator (explicit)
provide a method (like std::optional::has_value()) for use in templated methods
Note that if (...) performs an explicit bool-cast on the statement. So generally there is no need for implicit conversions. In order to avoid trouble using overloads, you should always go for explicit conversion-operators.

Declare object without calling default constructor

I'm new to C++, and am used to working with Java.
In Java, I have the option of declaring an object without instantiating it, and would like to do the same in C++.
Assuming there is some class Foo, in Java I could write Foo bar; to declare an instance of Foo without initializing bar.
However, in C++ when I write Foo bar;, bar is initialized by calling the default constructor of class Foo.
This is particularly vexing if I have written one or more constructors for class Foo, each of which have at least one argument. In this case, the code will fail to compile with an error similar to no matching function for call to 'Foo::Foo()'
For example, say I have the following class definition in Java:
public class Foo {
private boolean b;
Foo(boolean b) { this.b = b; }
}
and the corresponding class definition in C++:
class Foo {
bool b_;
public:
Foo(bool b) : b_(b) {}
};
In Java, I could write some method
public static Foo makeFoo(int x) {
Foo result;
if (x > 10) { result = new Foo(true); }
else { result = new Foo(false); }
return result;
}
However, if I write a similar method in C++, I get a compilation error:
Foo makeFoo(int x) {
Foo result; // here, a call is made to Foo::Foo() which doesn't exist, and thus compilation fails
if (x > 10) {
result = Foo(true); // this would probably also fail since I didn't specify a copy-constructor, but I'm not entirely sure
}
else {
result = Foo(false); // as above, I think this would probably fail
}
return result;
}
While the example I gave is useless, I frequently used this sort of approach when writing Java code.
Is there a way to emulate this behavior in C++?
Alternatively, is this just bad design? If so, what sort of approach would you recommend?
If you don't want to use pointers to get reference functionality as Igor (and others) explained in the first comment on your question, then you can do a couple of things.
First, the philosophy of value types instead of reference types is do not create them until you need them. Your temptation to declare the reference ahead of using the object to obtain a sort of polymorphic functionality in the remainder of the function (some post-create common init code, perhaps) is reasonable design, but cannot be expressed the way you wrote it because it would involve creating a value.
You could provide a default constructor and give it some behaviour -- but it's pretty clear that neither you nor anybody else want to be coerced into doing that.
The essence of the alternative is to move the variable inside the scope and return it.
Foo makeFoo(int x) {
if (x > 10) {
Foo result = Foo(true);
return result;
}
else {
Foo result = Foo(false);
return result;
}
}
Obviously this prevents you from writing common post-create init code after the if block before the return. To do that, you would write the if block in its own function and have it return the result, then write the follow up code after you've initialized your object.
Foo premakeFoo(int x) {
if (x > 10) {
Foo result = Foo(true);
return result;
}
else {
Foo result = Foo(false);
return result;
}
}
Foo makeFoo(int x) {
Foo result = premakeFoo(x);
// common post init code can go here.
return result;
}
If you don't want it in a completely separate function, you could do a lambda.
Foo makeFoo(int x) {
Foo result = ([=]() {
if (x > 10) {
Foo result = Foo(true);
return result;
} else {
Foo result = Foo(false);
return result;
}
})();
// common post init code can go here.
return result;
}
Or in your case, if it's small, use a ternary expression inline.
Foo makeFoo(int x) {
Foo result = (x > 10) ? Foo(true) : Foo(false); // or just Foo(x>10)
// common post init code can go here.
return result;
}
There are other clever options involving templates, but they all revolve around the idea of isolating the different expressions for the overloaded constructors and then using an assignment to initialize a variable given some more sophisticated expression. And what you are trying to do is to get the expression that constructs the value in two different ways to span a scope block (span the if blocks). Ternaries and functions are the options here for getting the if logic executed within a single expression.
In Java when you do Foo result; you create a reference to Foo, you don't actually create an object. C++ is different though since it has value semantics and Foo result; actually creates an object. If there is no default constructor, then an error is raised.
To get the same type of behavior you need to use pointers in C++. You can't use a reference since a reference needs to be bound to an object when it is created, unlike Java. So, if you use a std::unique_ptr<Foo> you can declare that, and then initialize it later with a std::unique_ptr<Foo> that you initialize in your creation logic. Using your example, the code would look like
Foo makeFoo(int x) {
std::unique_ptr<Foo> result; // here result doesn't have an actual object yet
if (x > 10) {
result = std::make_unique<Foo>(true); // now we pass the values we want to construct with and get a valid object
}
else {
result = std::make_unique<Foo>(false); // same as above
}
return *result; // this lets you return a `Foo` which will be a copy, and the Foo created by make_unique will be destroyed
}
If you don't want to make a copy, you can use return result; instead, and change the function to return a std::unique_ptr<Foo>.
what you are trying to do is called a factory pattern and is usually implemented in this way
std::unique_ptr<Foo> makeFoo(int x) {
std::unique_ptr<Foo> result = nullptr;
if (x > 10) {
result = std::make_unique<Foo>(true);
}
else {
result = std::make_unique<Foo>(false);
}
return result;
}
for the above to work you also need to include the header. refer to this for further information on unique_ptr and memory management in c++
also, note I would not recommend this level of verbosity in code, I wrote that out for presentation purposes. The following version offers fewer lines of code and is more elegant.
std::unique_ptr<Foo> makeFoo(int x) {
if (x > 10) {
return std::make_unique<Foo>(true);
}
return std::make_unique<Foo>(false);
}

Objects with primitive data pointers and emscripten

Rephrasing the question:
How should I bind a function that returns an object with an array as member variable from a C/C++ API to javascript when I don't know the length of the array a priori?
I have a struct with a primitive data type pointer
struct Person
{
const char* name;
int age;
Person()
{}
};
and I have a function that should return this an object of this struct
Person getPerson()
{
Person p = Person();
p.name = "Philipp";
p.age = 77;
return p;
}
and following embindings:
EMSCRIPTEN_BINDINGS() {
value_object<Person>("Person")
.field("age", &Person::age)
.field("name", &Person::name)
;
function("getPerson", &getPerson);
}
This doesn't work and the compiler also tells me static_assert failed "Implicitly binding raw pointers is illegal. Specify allow_raw_pointer<arg<?>>"
I tried to understand API documentation but I couldn't make it work. E.g. I tried to add allow_raw_pointer() (and variants of this) to the .field of name.
class_::property can specify getter and setter function.
std::string getPersonName(const Person& p) {
return p.name;
}
EMSCRIPTEN_BINDINGS() {
class_<Person>("Person")
.property("age", &Person::age)
.property("name", &getPersonName)
;
function("getPerson", &getPerson);
}
/*
var p = Module.getPerson();
console.log(p);
console.log(p.age);
console.log(p.name);
*/

Auto return type of a function in c++

I have a problem that Im not able to solve. I have tried to find similar question here, but didnt find working solution for me.
My structure is:
class Base
{
unsigned int ID;
};
class Position: public Base
{
float x,y;
Position(float a, float b): x(a), y(b) {}
}
class Mass: public Base
{
float mass;
Mass(float a): mass(a) {}
}
I store pointers to all attributes in a map accesed with strings.
I would like to have a function, that can return any attribute from this list using names.
Structure and desired functionality should be like this:
std::map<string, Base*> attributes;
???? getAtt(string name)
{
return attributes[name];
}
Position pos(1,2);
Mass mass(25.6);
attributes.emplace("TEST_POSITION", &pos);
attributes.emplace("TEST_MASS") &mass);
cout << "Mass of this object is " <<getAtt("TEST_MASS").mass << endl;
cout << "X - Position of this object is " << getAtt("TEST_POSITION").x ;
PRINTS: Mass of this object is 25.6
X - Position of this object is 1
This function, addition of attributes and memory managment should be encapsuled in another class, but I think that wont be such problem after i get this thing solved.
So is there a way to do that? I was thinking about templates, but I dont understand them enough to make them work :( I was thinking about not storing all attributes in one array, but this way it is really easy.
Thanks for any suggestions :)
Your getAtt will return a Base*, like this:
Base* getAtt(const string& name)
{
...
}
But Base class doesn't provide a interface for all its derived class, so you can't just do
getAtt("TEST_MASS").mass
instead you have to do this:
dynamic_cast<Mass*>(getAtt("TEST_MASS"))->mass;
dynamic_cast<Position*>(getAtt("TEST_POSITION"))->x;
There are alternatives, for example you can use a tagged union, but that might be too complex for your problem.
By the way, [] operator of map will create a element if it doesn't exist, so you need to check getAtt isn't returning a nullptr.
The compiler cannot deduce the return type without you hinting it. You can use a template for that:
template <typename T>
T& getAtt(string name)
{
return dynamic_cast<T&>(*attributes.at(name));
}
Edit: use at instead of [], [] has the side-effect that it creates non-existing keys.
And then call it like this:
getAtt<Mass>("TEST_MASS").mass
getAtt<Position>("TEST_POSITION").x
However, this code would be nightmare to debug. Try to avoid generic attributes and use strong-typed variables, ie. instead of:
std::map<string, Base*> attributes;
attributes.emplace("mass", Mass(…));
attributes.emplace("position", Position(…));
use:
Mass mass;
Position position;
You can return a reference object that has a conversion operator to the type. If the conversion is implemented with a dynamic cast, the result will be NULL if an attempt is made to assign the object to something that it is not. Dynamic cast requires Base to have a virtual method (you could just add a virtual destructor).
class Base {
unsigned int ID;
protected:
virtual ~Base () {}
};
class Ref {
friend Ref getAtt (std::string name);
Base *ref_;
Ref (Base *p = 0) : ref_(p) {}
public:
template <typename D> operator D * () const {
return dynamic_cast<D *>(ref_);
}
};
Ref getAtt (std::string name) { return attributes[name]; }
This technique does not allow you to treat a Ref as any particular type. It allows you to assign it to something that it is allowed to become.
Mass *m = getAtt("TEST_MASS");
Position *p = getAtt("TEST_POSITION");
cout << "Mass of this object is " << m->mass << endl;
cout << "X - Position of this object is " << p->x ;
If the resulting pointer is NULL, it means either the item did not exist, or you are attempting to assign it to the wrong thing.
Position *p = getAtt("TEST_MASS");
assert(p == NULL);