TypeScript dynamic property type on class - dynamic

There is a way to declare the type of dynamic class property if it's accessed by [] operator, like on the following example:
class Foo {
[key: string]: number;
}
let a = new Foo();
let b = a['bar']; //Here, the compiler knows that b is a number
But is there a way to declare the same thing, without [] operator?
A way to write this:
let a = new Foo();
let b = a.someProperty;
And letting TypeScript knows that someProperty is of type number, because we say to it: All unknown properties on Foo are of type number.

I do not think its is possible. When you define class you define 'static' information about its properties and methods. If you specify indexer - it means just that - that the objects of the class will have indexer, not any properties. Thats what classes are for after all - to define structure of your business entities.
The only way I am aware of doing something similar to what you want is by using object literals. For example this will work:
let x: { PropA: number, [x: string]: number };
x = { PropA: 1, PropX: 2, PropY: 3, PropZ: 4 };
Hope this helps.

Related

How to add an "Item" object to an Object ArrayList in kotlin

I have the following class
class Item {
var name: String = ""
constructor(n: String) {
name = n
}
}
On my main activity I have declared this:
var list: ArrayList<Object> = ArrayList<Object>()
When I try to do this
list.add(Item("Hey friend"))
The compiler complains about type mismatch (Object -> Item) which is obviously true but since Item is also an Object, shouldn't this be fine? I'm pretty sure you can do this in Java, whats the alternative?
I need the list to be of type object because I have to store different stuff in there, so changing it is not an option.
The supertype of all types in Kotlin is Any, not Object.
Other things you can improve in var list: ArrayList<Object> = ArrayList<Object>():
make it a val because immutability is preferred
If you need an explicit type declaration, use the interface List<Any
use Kotlin's collection builders listOf()
val items: List<Any> = listOf()`
Also, the class definition can be reduced to
class Item(val name: String) //could even be a data class

Observable array in Kotlin to know when an array elt value is changed

My goal: I have a simple class with a public
val reds = IntArray(10)
val greens = IntArray(10)
val blues = IntArray(10)
val lums = IntArray(10)
If someone modifies any red value, I'd like to update the lum value.
myObj.reds[5] = 100 // Should update myObj.lums[5] = reds[5]+greens[5]+blues[5]
The problems is that the by Delegates.observable seem to only be used for var objects - nothing mentions "and if you modify an element of an array, here is what gets triggered"
Maybe this isn't possible and I have to do all modifications through getters and setters - but I'd much rather have something trigger like an observable!
You will have to use a custom class instead, IntArray is mapped to primitive int[] array so it doesn't provide any place to inject callback - changing value like your example (myObj.reds[5] = 100) you only know when array is returned, but have no control over changes after that.
For example you can create class like this:
class IntArrayWrapper(size: Int,
val setterObs : ((index: Int, value: Int) -> Unit)? = null){
val field = IntArray(size)
val size
get() = field.size
operator fun iterator() = field.iterator()
operator fun get(i: Int) : Int {
return field[i]
}
operator fun set(i: Int, value: Int){
field[i] = value
setterObs?.invoke(i, value)
}
}
Operator functions will let you get values from underlying array with same syntax as if you were accessing it directly. setterObs argument in constructor lets you pass the "observer" for setter method:
val reds = IntArrayWrapper(10){index, value ->
println("$index changed to $value")
invalidateLums(index) // method that modifies lums or whatever you need
}
val a = reds[2] // getter usage
reds[3] = 5 // setter usage that triggers the setter observer callback
reds.field[4] = 3 // set value in backing array directly, allows modification without setter callback
Note that this imposes limitations, as you won't be able to freely use IntArray extension methods without referencing backing field nor will you be able to pass this class as an Array argument.
I do not know if it is the cleanest way of solving your problem but, you could use the ObservableList (FX observable collections):
var numbers: ObservableList<Int> = FXCollections.observableArrayList()
numbers.addListener(ListChangeListener<Int> {
//Do things on change
})
But as I mentioned, by adding these collections you are mixing FX components into your application, which I do not know if it is wanted or even if it works on various platforms like android!

Pass an Integer by Reference in Kotlin

I am trying to create a swap function which takes in two parameters as shown below:
fun swap(a :Int, b:Int) {
}
I call it like this:
var a = 10
var b = 5
swap(a,b)
// a should be 5
// b should be 10
The problem is that even if I swap the values inside the swap function it won't be reflected on the caller's side because it is passed as a copy and not as a reference.
Is there anyway to pass value types to swap function and allow the function the ability to change them.
There is absolutely no way to do it directly. Kotlin copies a value for scalar types (Double, Float, Boolean, Int, etc.). So any internal changes are lost.
For any other type, Kotlin copy a reference of parameter passed to the function. So any property/field alteration of parameter, also changes the caller parameter.
There is no way to change this behaviour.
After trying many ways to overcome the impossibility of passing scalar by reference, as happens in Kotlin, Java and some other languages; my current strategy is using for any scalar type a plain and generic wrap, as an above comment suggest.
Recently, I'm using this trick for everything, including inside a function that otherwise would demand that I return multiple values. The alternative is joining the returns in a artificial class or destructuring declarations: val (a, b, c) = function-call() syntax. However, I hate articial classes and destructuring declaration is for local variables only, and it's annoying when some needs visibility out of current block of commands.
My code is very simple:
data class p<T>( // It's a generic wrap class for scalar type T
var v:T
)
fun <T>swap(a:p<T>, b:p<T>){ // It's a generic swap for scalar types
var aux:p<T> = a.copy()
a.v = b.v
b.v =aux.v
}
fun main() {
var a:p<Int> = p<Int>(2) // 'a' is a kind of 'Int' variable
var b:p<Int> = p<Int>(3) // and so is 'b'
swap(a,b) // Exchange 'a' and 'b' values
println(a.v) // 3
println(b.v) // 2
}
The only drawback is not being able to use syntax sugar of a real scalar type.
I am forced to add .v on any use of a scalar variable.
I only uses that for variables that I need pass by reference in some function and it's not so common. I try, when possible, avoid collateral effects.
You can have a function that gets the references of variables
var x = 10
var y = 20
fun main() {
println("x=$x, y=$y") // x=10, y=20
swap(::x, ::y)
println("x=$x, y=$y") // x=20, y=10
}
fun <T> swap(firstRef: KMutableProperty0<T>, secRef: KMutableProperty0<T>) {
val temp = firstRef.get()
firstRef.set(secRef.get())
secRef.set(temp)
}
and you can pass the references of properties of some class like this swap(someClass::x, someClass::y)
the only limitation is that you can't pass references of local variables which is not the end of the world.
if you don't like the messy syntax you can always define a typealias and make it pretty:
typealias Ref<T> = KMutableProperty0<T>
fun <T> swap(firstRef: Ref<T>, secRef: Ref<T>) {
...
}
I know that OP didn´t ask for this, but idiomatic Kotlin would look like:
var a = 1
var b = 2
a = b.also { b = a }
Seems like Kotlin behaves pretty much like Java does:
Is Kotlin "pass-by-value" or "pass-by-reference"?
simple way to swap is make support class
private fun swap(pair: Pair) {
pair.a += pair.b
pair.b = pair.a - pair.b
pair.a = pair.a - pair.b
}
private data class Pair(var a: Int, var b: Int)
fun main() {
val pair = Pair(10, 5)
swap(pair)
println(pair)
}

Extension fields in Kotlin

It's easy to write extension methods in Kotlin:
class A { }
class B {
fun A.newFunction() { ... }
}
But is there some way to create extension variable? Like:
class B {
var A.someCounter: Int = 0
}
You can create an extension property with overridden getter and setter:
var A.someProperty: Int
get() = /* return something */
set(value) { /* do something */ }
But you cannot create an extension property with a backing field because you cannot add a field to an existing class.
No - the documentation explains this:
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on instances of this class.
and
Note that, since extensions do not actually insert members into classes, there’s no efficient way for an extension property to have a backing field. This is why initializers are not allowed for extension properties. Their behavior can only be defined by explicitly providing getters/setters.
Thinking about extension functions/properties as just syntactic sugar for calling a static function and passing in a value hopefully makes this clear.
However, if you really, really want to do something like this...
As stated above regarding efficiency, an additional backing field added directly to the class is the best way to store data non-derivable from existing non-private members from the class. However, if you don't control the implementation of the class and are dead-set on creating a new property that can store new data, it can be done in a way that is not abysmally inefficient by using separate external tables. Use a separate map that keys on object instances of this class with values that map directly to the value you want to add then define an extension getter and/or setter for this property which uses your external table to store the data associated with each instance.
val externalMap = mutableMapOf<ExistingClass, Int>()
var ExistingClass.newExtensionProperty : Int
get() = externalMap[this] ?: 0
set(value:Int) { externalMap[this] = value }
The additional map lookups will cost you - and you need to consider memory leaks, or using appropriately GC-aware types, but it does work.
There's no way to add extension properties with backing fields to classes, because extensions do not actually modify a class.
You can only define an extension property with custom getter (and setter for var) or a delegated property.
However, if you need to define an extension property which would behave as if it had a backing field, delegated properties come in handy.
The idea is to create a property delegate that would store the object-to-value mapping:
using the identity, not equals()/hashCode(), to actually store values for each object, like IdentityHashMap does;
not preventing the key objects from being garbage collected (using weak references), like WeakHashMap does.
Unfortunately, there is no WeakIdentityHashMap in JDK, so you have to implement your own (or take a complete implementation).
Then, based on this mapping you can create a delegate class satisfying the property delegates requirements. Here's an example non-thread-safe implementation:
class FieldProperty<R, T : Any>(
val initializer: (R) -> T = { throw IllegalStateException("Not initialized.") }
) {
private val map = WeakIdentityHashMap<R, T>()
operator fun getValue(thisRef: R, property: KProperty<*>): T =
map[thisRef] ?: setValue(thisRef, property, initializer(thisRef))
operator fun setValue(thisRef: R, property: KProperty<*>, value: T): T {
map[thisRef] = value
return value
}
}
Usage example:
var Int.tag: String by FieldProperty { "$it" }
fun main(args: Array<String>) {
val x = 0
println(x.tag) // 0
val z = 1
println(z.tag) // 1
x.tag = "my tag"
z.tag = x.tag
println(z.tag) // my tag
}
When defined inside a class, the mapping can be stored independently for instances of the class or in a shared delegate object:
private val bATag = FieldProperty<Int, String> { "$it" }
class B() {
var A.someCounter: Int by FieldProperty { 0 } // independent for each instance of B
var A.tag: String by bATag // shared between the instances, but usable only inside B
}
Also, please note that identity is not guaranteed for Java's primitive types due to boxing.
And I suspect the performance of this solution to be significantly worse than that of regular fields, most probably close to normal Map, but that needs further testing.
For nullable properties support and thread-safe implementation please refer to here.
You can't add a field, but you can add a property, that delegates to other properties/methods of the object to implement its accessor(s). For example suppose you want to add a secondsSinceEpoch property to the java.util.Date class, you can write
var Date.secondsSinceEpoch: Long
get() = this.time / 1000
set(value) {
this.time = value * 1000
}
If you are extending View you can do it quite easily like this...
This is example how I create some my custom class Event property in EditText class extension:
Define id for key :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="EditTextEventOnClearTagKey" type="id" />
</resources>
Define one reusable extension like this:
fun <T : Any> View.tagProperty(#IdRes key: Int, onCreate: () -> T): T {
#Suppress("UNCHECKED_CAST")
var value = getTag(key) as? T
if (value.isNull) {
value = onCreate()
setTag(key, value)
}
return value!!
}
Use it in wherever View extension you need:
val EditText.eventClear get() = tagProperty(R.id.EditTextEventOnClearTagKey) { event<Unit>() }

Constructors in Go

I have a struct and I would like it to be initialised with some sensible default values.
Typically, the thing to do here is to use a constructor but since go isn't really OOP in the traditional sense these aren't true objects and it has no constructors.
I have noticed the init method but that is at the package level. Is there something else similar that can be used at the struct level?
If not what is the accepted best practice for this type of thing in Go?
There are some equivalents of constructors for when the zero values can't make sensible default values or for when some parameter is necessary for the struct initialization.
Supposing you have a struct like this :
type Thing struct {
Name string
Num int
}
then, if the zero values aren't fitting, you would typically construct an instance with a NewThing function returning a pointer :
func NewThing(someParameter string) *Thing {
p := new(Thing)
p.Name = someParameter
p.Num = 33 // <- a very sensible default value
return p
}
When your struct is simple enough, you can use this condensed construct :
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33}
}
If you don't want to return a pointer, then a practice is to call the function makeThing instead of NewThing :
func makeThing(name string) Thing {
return Thing{name, 33}
}
Reference : Allocation with new in Effective Go.
There are actually two accepted best practices:
Make the zero value of your struct a sensible default. (While this looks strange to most people coming from "traditional" oop it often works and is really convenient).
Provide a function func New() YourTyp or if you have several such types in your package functions func NewYourType1() YourType1 and so on.
Document if a zero value of your type is usable or not (in which case it has to be set up by one of the New... functions. (For the "traditionalist" oops: Someone who does not read the documentation won't be able to use your types properly, even if he cannot create objects in undefined states.)
Go has objects. Objects can have constructors (although not automatic constructors). And finally, Go is an OOP language (data types have methods attached, but admittedly there are endless definitions of what OOP is.)
Nevertheless, the accepted best practice is to write zero or more constructors for your types.
As #dystroy posted his answer before I finished this answer, let me just add an alternative version of his example constructor, which I would probably write instead as:
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33} // <- 33: a very sensible default value
}
The reason I want to show you this version is that pretty often "inline" literals can be used instead of a "constructor" call.
a := NewThing("foo")
b := &Thing{"foo", 33}
Now *a == *b.
There are no default constructors in Go, but you can declare methods for any type. You could make it a habit to declare a method called "Init". Not sure if how this relates to best practices, but it helps keep names short without loosing clarity.
package main
import "fmt"
type Thing struct {
Name string
Num int
}
func (t *Thing) Init(name string, num int) {
t.Name = name
t.Num = num
}
func main() {
t := new(Thing)
t.Init("Hello", 5)
fmt.Printf("%s: %d\n", t.Name, t.Num)
}
The result is:
Hello: 5
I like the explanation from this blog post:
The function New is a Go convention for packages that create a core type or different types for use by the application developer. Look at how New is defined and implemented in log.go, bufio.go and cypto.go:
log.go
// New creates a new Logger. The out variable sets the
// destination to which log data will be written.
// The prefix appears at the beginning of each generated log line.
// The flag argument defines the logging properties.
func New(out io.Writer, prefix string, flag int) * Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
bufio.go
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) * Reader {
return NewReaderSize(rd, defaultBufSize)
}
crypto.go
// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
panic("crypto: requested hash function is unavailable")
}
Since each package acts as a namespace, every package can have their own version of New. In bufio.go multiple types can be created, so there is no standalone New function. Here you will find functions like NewReader and NewWriter.
In Go, a constructor can be implemented using a function that returns a pointer to a modified structure.
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
For weak dependencies and better abstraction, the constructor does not return a pointer to a structure, but an interface that this structure implements.
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}
another way is;
package person
type Person struct {
Name string
Old int
}
func New(name string, old int) *Person {
// set only specific field value with field key
return &Person{
Name: name,
}
}
If you want to force the factory function usage, name your struct (your class) with the first character in lowercase. Then, it won't be possible to instantiate directly the struct, the factory method will be required.
This visibility based on first character lower/upper case work also for struct field and for the function/method. If you don't want to allow external access, use lower case.
Golang is not OOP language in its official documents.
All fields of Golang struct has a determined value(not like c/c++), so constructor function is not so necessary as cpp.
If you need assign some fields some special values, use factory functions.
Golang's community suggest New.. pattern names.
I am new to go. I have a pattern taken from other languages, that have constructors. And will work in go.
Create an init method.
Make the init method an (object) once routine. It only runs the first time it is called (per object).
func (d *my_struct) Init (){
//once
if !d.is_inited {
d.is_inited = true
d.value1 = 7
d.value2 = 6
}
}
Call init at the top of every method of this class.
This pattern is also useful, when you need late initialisation (constructor is too early).
Advantages: it hides all the complexity in the class, clients don't need to do anything.
Disadvantages: you must remember to call Init at the top of every method of the class.