When trying to expose the topMargin as alias in the root component I get the following error:
Invalid alias target location: topMargin
The code is the following:
import QtQuick 2.6
Item {
id: root
property alias textTopMargin: description.anchors.topMargin
Text {
id: description
}
I can't find any information in the documentation about aliases and anchors, it is forbidden?
EDIT:
Seem that is caused by this: https://bugreports.qt.io/browse/QTBUG-65011
EDIT2:
The bug has been closed as invalid, the reason seems that is documented here:
https://codereview.qt-project.org/c/qt/qtdeclarative/+/215724
My reasoning for why it does not work (I don't have proof)
Let's assume you have the following:
// SomeObject.qml
QtObject {
property int someProperty: 5
}
// SomeItem.qml
Item {
property SomeObject someObject: SomeObject {}
}
Now you have the second Item:
// SomeOtherItem.qml
Item {
property alias someProperty: smeItm.someObject.someProperty
SomeItem {
id: smeItm
}
}
And now you somewhere set a new SomeObject to smeItm.someObject, what will be aliased? The original SomeObject or the new? If you would alow arbitrary chains, you would need to make sure that the reference stays valid and does not change.
From the documentation:
Unlike an ordinary property, an alias can only refer to an object, or the property of an object, that is within the scope of the type within which the alias is declared. It cannot contain arbitrary JavaScript expressions and it cannot refer to objects declared outside of the scope of its type.
That is not completely obvious, but you can read it as: A alias expression has one of those forms:
objectId
objectId.propertyName
Related
So I have a class with a generic type
class GenericClass<T> {
// At some point in the class I have variable item of type T
val name: String = item.name
}
I know for sure that the type T of GenericClass will be used with a class that has the "name" property. But of course at the line I got a "Unresolved reference name". Android Studio generated me this code via "Create extension property T.name"
private val <T> T.name: String
get() {}
I don't really know what to put in the bracket {} after the get. I tried return name but I got a recursive property error.
Any ideas ?
Thanks
If you know that every type T has property name you can declare it implicitly:
// GenericClass.kt
class GenericClass<T : HasName> {
// At some point in the class I have variable item of type T
val name: String = item.name
}
// HasName.kt
// Create new interface with "name" property
interface HasName {
val name: String
}
But also you must implement this new interface for all classes that can be used as T.
I know for sure that the type T of GenericClass will be used with a class that has the "name" property.
Then you need to explicitly declare that. By default, T extends Any?. You need to narrow down possible types of T by declaring some interface, like
interface Named {
val name : String
}
and passing T : Named as a generic paramteter. Also you need to make all classes, you're going to pass as a generic parameter, to implement that interface. By the way, GenericClass<T : Named> class itself could be declared as implementing that interface:
class GenericClass<T : Named> : Named {
override val name: String = item.name
}
What is it called when you define a variable/property with a getter and setter, such that the language does not automatically generate a backing variable?
E.g. in Swift, we could define a modalViewController property that doesn't create a backing variable:
extension MyViewController {
var modalViewController: UIViewController? {
get { return self.presentedViewController }
set { self.present(newValue, animated: true) }
}
}
What's the proper term to describe the modalViewController property?
I know that if it's only gettable, it would be called a computed property:
extension Int {
var isEven: Bool {
get { return self % 2 == 0 }
}
}
However, I'm looking for a term for something that is both settable and gettable.
The reason I'm looking for a term is that I want to ask a question related to these types of properties, and would like to use common, non-ambiguous language. I thought this would be called a virtual property, but it doesn't appear to be the proper name as virtual has a different meaning in OOP.
Even though they have a setter too, Swift (at least) calls these "computed properties" (emphasis added):
In addition to stored properties, classes, structures, and enumerations can define computed properties, which do not actually store a value. Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly.
I'm new to properties and moved from the java to kotlin. I'm struggling with the properties, I learned much about it but initializing the properties are confusing me, when it should be initialized or when it can work without initialization.
Let me explain it by the help of code. Below is the code which is requiring to initialize the property when the back-end field generated, before posting the code let me post the paragraph from the kotlin official website.
A backing field will be generated for a property if it uses the
default implementation of at least one of the accessors, or if a
custom accessor references it through the field identifier.
Now here is the code below.
class Employee{
var data: String // because there are default implementation of get set
// so there will be a back-end field.
}
So I have to initialize it else compilation error.
Ok I can understand it as that some one can access it so there will be no value which can produce the wrong result.
Then I move next to understand it more, so I add custom getter.
class Employee{
var data: String
get() = "default value"
}
This also generate the back-end field so compilation error to initialize it. I can understand it as that there is no initialized value so compiler complain about it.
May be compiler is not smart enough yet to check that there is value which is giving result for this property by custom getter so don't complain about initializing just return that value when required.
But there should be not a problem if any one access it then a default value is already there, then why compiler still complain?
Then I move one step more to implement custom setter too.
class Employee{
var data: String
get() = "default value"
set(value){
field = value
}
}
Still there is the back-end field because we have accessed the field so compiler generate the back-end field.
Same error, should be initialized.
Then the final stage where it works fine as below.
class Employee{
var data: String
get() = "default value"
set(value){
}
}
Now I'm not accessing field in custom getter setter so there is not a back-end field. And it works fine.
So the final question when the property should be intialized? When there is a back-end field generated?
Yes this does not compile:
class Employee{
var data: String
get() = "default value"
}
but this does:
class Employee{
val data: String
get() = "default value"
}
so maybe the compiler by stating Property must be initialized for the wrong declaration, wants from you to admit that data is something that you can not change. I say maybe.
Now the part that does compile:
class Employee{
var data: String
get() = "default value"
set(value){
}
}
This is where you explicitly admit that whatever happens I will never set a value to data, and that's why the compiler feels fine.
Just to save you from more confusion, there's a lot of explaining about Kotlin in the Internet and you may find it very difficult to get familiarized with this relatively new language, but keep in mind that everything needs to be tested by you.
I found the below code in a web page:
class User{
var firstName : String
get() = field
set(value) {field = value}
var lastName : String
get() = field
set(value) {field = value}
}
and it is presented as compilable when it's not.
You kind of answered your own question. There's no backing field when you override both getter and setter, and don't access field.
About your "compiler not being smart enough": get() function is actually RAN at runtime, so writing a lot of compiler code just to evaluate if return value is static and should be injected as default is too niche of a use case.
If your getter depends on another field which is only initialized later, this would cause a lot of confusion as to what default value should be.
Consider this code, assuming value of provider is not defined:
var data: String
get() = provider.data
What would be a default value? Do you want a null? Empty string? Maybe entire object initialization should crash? Explicit default value declaration is needed for that purpose.
That's where idea of lateinit var came to be: if You're certain you will set value before performing any get, You can use this keyword to prevent compiler errors and setting default value.
class Employee{
var data: String
get() = "default value"
}
var means there are both a getter and a setter. Because you didn't write a setter, you get the default one, which accesses the backing field. So there is a backing field, and it needs to be initialized.
But there should be not a problem if any one access it then a default value is already there, then why compiler still complain?
Because that makes the rules simpler: all properties with backing fields must be initialized. This in turn may be because in Java fields don't have to be initialized and this is a known source of bugs. I would like to say it also avoids a possible bug, because presumably you don't actually want the setter's result never to be accessible, but initializing doesn't fix that problem.
I don't see any obvious problem with changing the rules so that a field only needs to be initialized when accessed in the getter, and maybe adding a warning when only one accessor uses field. But I may be missing something, and don't see much benefit to doing so either.
So, the question is in the title. I declared some properties in my classes using 'never' keyword so I may set the values of these properties only once, in the constructor. However, I get the following error:
Cannot access field or identifier %name% for writing
Example of the problematic code:
class TreeAbility
{
public var id(default, never):String;
public var maxLvl(default, never):Int;
public function new(id:String, maxLvl:Int)
{
Assert.assert(maxLvl > 0);
this.id = id; (*)
this.maxLvl = maxLvl; (*)
this.currentLvl = 0;
}
}
The lines marked with (*) throw the access error
I believe the never write property means that writing/setting the variable is never allowed, not even within the constructor. See: https://haxe.org/manual/class-field-property.html
Perhaps you are looking for the final keyword, which is coming in Haxe 4. For instance fields, it allows assignment to the variable only from the class constructor. Confirmed here: https://haxe.org/download/version/4.0.0-preview.2/ and https://github.com/HaxeFoundation/haxe/issues/6584
I am trying to create instances of class HelloWorld, however it does not work. I found that problem is that setter methods called instead of constructor which should initialize variable name, while variable welcome is optional.
I specified getters and setters for both variables. Browser's console is throwing an error about maximum call stack size. If I comment my getters&setters it stops throwing errors.
Could anyone explain me that strange behaviour?
Also there is another problem with mapping. I'm trying to "return" an array if li elements like in React by using .map(). It gives me the result with commas. How can I get rid of them while printing?
This is a link to my code https://codepen.io/CrUsH20/pen/yzMjzL?editors=1010
Updated #1
I fixed the problem with getters&setters by giving a _ sign for private values.
Now I have a problem with
function print() {
if (invitations) {
document.getElementById('result').innerHTML = invitations.map((e)=> {
return `<li>${e.welcome + e.name}</li>`;
});
}
}
Compiler complains that Type 'string[]' is not assignable to type 'string'. in document.getElementById('result').innerHTML while type was not assigned since it is a html element
Update #2
There are solutions:
1# About conflict with constructor and set&get - I changed object's values by adding to their names _. It solved the conflicts.
2# About commas - I added after map .join('') which solved my problem.
The following code (subset of yours) is a compile error:
class HelloWorld {
constructor(public name: string) {
}
set name(e: string) {
this.name = e;
}
get name(): string {
return this.name;
}
}
Garbage in => Garbage out
Fix
Dont use getter / setters and properties with the same name.