Creating an enum in Swift, exportable to ObjC, based on another enum: String - objective-c

I have an enum Foo: String in Swift (therefore not exportable to Objective-C) and I'm trying to create another enum FooObjc in Swift to kinda "wrap" the existent one so that it is 1) available to use in Objective-C and 2) convertable back and forth (Foo <=> FooObjc). The original Foo enum is part of a framework that I don't want to modify. Of course, it's very easy to do what I want if I use a class instead, like this:
#objc public class FooObjc: NSObject {
public private(set) var foo: Foo
#objc public var string: String {
return foo.rawValue
}
#objc public init?(string: NSString) {
guard let foo = Foo(rawValue: string as String) else {
return nil
}
self.foo = foo
}
internal init(foo: Foo) {
self.foo = foo
}
}
(PS: not able to inherit from NSString because the Swift compiler still doesn't accept creating initializers for that class)
Ok, but I definitely don't like this approach because then my Objective-C code will be string-typed. I really want to use an enum instead because after all, that's what it is. This is the least bad working version I could get:
#objc public enum FooObjc: Int, RawRepresentable {
case undefined = -1
case bar
case baz
// omitting many more cases
internal init?(_ foo: Foo?) {
if let foo = foo {
self = fooMapping.filter { $1 == foo }.map { $0.key }.first!
} else {
self = .undefined
}
}
// MARK: - RawRepresentable
public typealias RawValue = String
public init?(rawValue: RawValue) {
let filter = fooMapping.filter { $1?.rawValue == rawValue }
guard filter.count > 0 else {
return nil
}
self = filter.map { $0.key }.first!
}
public var rawValue: RawValue {
switch (self) {
case .undefined: return "undefined"
case .bar: return Foo.bar.rawValue
case .baz: return Foo.baz.rawValue
// omitting many more cases
}
}
}
private let fooMapping: [FooObjc: Foo?] = [
.undefined : nil,
.bar : .bar,
.baz : .baz
// omitting many more cases
]
Notice that:
the fooMapping is useful to avoid one switch-case for each initializer
this undefined case was necessary because in Swift you can have optional enum properties, in Objective-C you can't, so this case will directly map to a Foo? which value is nil.
What worries me here is that I had to write the same cases from the original Foo three times... I'm completely satisfied if I repeat it only twice, but I wasn't able to use the fooMapping in the rawValue property because then I get a cycle between these two.
Note: I'm not sure if this is relevant to the question, but in the original enum, some of the cases have special String attributions, e.g. we have simply case bar but we also have case baz = "something".
So, the question is: does anyone have suggestions to improve this approach or even suggest something completely new that would avoid so much code repetition?
Thank you very much!

What worries me here is that I had to write the same cases from the original Foo three times
Consider an array ["bar", "baz" ...]. By looking at the index of a string in this array and making the necessary adjustments, you can translate from a string to an integer (and thence, via raw value, to a case). By indexing into the array and making the necessary adjustments, you can translate from an integer to a string (and thence, via raw value, to a case). So you will only have to write out the string values once. This eliminates two of your repetitions.
You will still have to write out the case names in the enum declaration, because there's no other way to tell Objective-C the names of the cases. The way to eliminate that repetition, obviously, is to be willing to change the implementation of Foo itself so that it becomes Objective-C-compatible. But you have stated up front that you refuse to do that, so now you must pay the price.

Related

What is the use of open properties in Kotlin?

I have been learning Kotlin and have come across the concept of open properties. Coming from C++, the concept of "open" makes sense, and extending that logic to properties does as well. However, I can't think of any case where an open val/var is actually necessary or useful. I understand when they make sense for interfaces, but not concrete classes. Furthermore, overriding getters/setters makes sense, but not redefining the property with a new backing field. For example, say you have this kind of class structure:
open class Foo {
open var str = "Hello"
}
class Bar : Foo() {
override var str = "world"
init {
println(str)
println(super.str) // Shows that Bar actually contains "hello" and "world"
}
}
To me, it would seem to be a far better design to make Foo take str as a constructor argument, for instance:
open class Foo(var str = "Hello") // Maybe make a secondary constructor
class Bar : Foo("world") // Bar has only 1 string
This is both more concise, and seems to often be a better design. This is also the way it tends to be done in C++, so maybe I just don't see the benefit of the other way. The only possible time I can see overriding a val/var with a new one is if it for some reason needs to use super's value, like in
override val foo = super.foo * 2
Which still seems pretty contrived.
When have you found this useful? Does it allow for greater efficiency or ease of use?
open fields let you re-define getter and setter methods. It's practically pointless if you just return constants. However altering getter / setter behavior has (infinite) potential, so I'll just throw some ideas:
// propagate get/set to parent class
class Bar : Foo() {
override var str
get() = super.str.toUpperCase()
set(value) {
super.str = value
}
}
// creates a backing field for this property
class Bar : Foo() {
override var str = "World"
get() = field.toLowerCase()
// no need to define custom set if we don't need it in this case
// set(value) { field = value }
}
// instead of writing custom get/set, you can also use delegates
class Bar : Foo() {
override var str by Delegates.observable("world"){ prop, old, new ->
println("${prop.name} changed from $old to $new")
}
}

Is there an elegant kotlin way of convincing the compiler that a nullable field to which I just assigned a real value can't be null anymore?

I have read that using !! should generally be avoided.
Is there a way to write the following code in a more elegant way without having to add something like obsolete null checks and duplicated or dead blocks of code?
class A(var field: Thing?) {
fun getField(): Thing {
if (field == null) {
field = Thing()
}
return field!!
}
}
Also I don't understand why the compiler requires the !!-'pray-this-isn't-null-operator' to be satisfied in this scenario.
EDIT: Consider that it is important to me that a potential solution uses lazy initialization if the field is null!
Problem
As Enzokie already mentioned in the comments, another thread could have changed field after the null check. The compiler has no way of knowing that, so you have to tell it.
class A(var field: Thing?) {
fun getField(): Thing {
if (field == null) {
field = Thing()
}
// another thread could have assigned null to field
return field!! // tell the compiler: I am sure that did not happen
}
}
Solution (Eager)
In you particular case it would be a good idea to use a parameter f (you could name it "field" too, but I avoided that for clarity) in the constructor (without val/var) and afterwards assign it to a property field to which you assign either f or a new instance of Thing.
This can be expressed really concise with the Elvis operator :? which takes the left hand side if not null and the right hand side of the expression otherwise. So, in the end field will be of type Thing.
class A(f: Thing?) {
val field = f ?: Thing() // inferred type Thing
}
Solution (Lazy)
Since it was mentioned by gidds, if you need to initialize field lazyly you could do it like this using delegated properties:
class A(f: Thing?) {
val field by lazy {
f ?: Thing() // inferred type Thing
}
}
The call site does not change:
val a = A(null) // field won't be initialized after this line...
a.field // ... but after this
How about this?
class A(field: Thing?) {
private lateinit var field: Thing
init {
field?.let { this.field = it }
}
fun getField(): Thing {
if (!this::field.isInitialized) {
field = Thing()
}
return field
}
}
When you define a field, you actually define a variable plus two accessor methods:
val counter: Integer = 0
It is possible to customize the accessor methods by writing this instead:
val n = 0
val counter: Integer
get() = n++
This will execute the n++ each time you access the counter field, which therefore returns different values on each access. It is uncommon and unexpected but technically possible.
Therefore the Kotlin compiler cannot assume that two accesses to the same field return the same value twice. Usually they do, but it is not guaranteed.
To work around this, you can read the field once by copying it into a local variable:
fun count() {
val counter = counter
println("The counter is $counter, and it is still $counter.")
}

Convert a nullable type to its non-nullable type?

I have a bunch of beans that have nullable properties like so:
package myapp.mybeans;
data class Foo(val name : String?);
And I have a method in the global space like so:
package myapp.global;
public fun makeNewBar(name : String) : Bar
{
...
}
And somewhere else, I need to make a Bar from the stuff that's inside Foo. So, I do this:
package myapp.someplaceElse;
public fun getFoo() : Foo? { }
...
val foo : Foo? = getFoo();
if (foo == null) { ... return; }
// I know foo isn't null and *I know* that foo.name isn't null
// but I understand that the compiler doesn't.
// How do I convert String? to String here? if I do not want
// to change the definition of the parameters makeNewBar takes?
val bar : Bar = makeNewBar(foo.name);
Also, doing some conversion here with foo.name to cleanse it every time with every little thing, while on the one hand provides me compile-time guarantees and safety it is a big bother most of the time. Is there some short-hand to get around these scenarios?
You need double exclamation mark like so:
val bar = makeNewBar(foo.name!!)
As documented in Null Safety section:
The third option is for NPE-lovers. We can write b!!, and this will
return a non-null value of b (e.g., a String in our example) or throw
an NPE if b is null:
val l = b!!.length
Thus, if you want an NPE, you can have it, but you have to ask for it explicitly, and it does not appear out of the
blue.
You could use an extension:
fun <T> T?.default(default: T): T {
return this ?: default
}
Then use it like this:
fun getNonNullString(): String {
return getNullableString().default("null")
}

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.

Best design for lookup-and-possibly-change method

I am designing a class that stores (caches) a set of data. I want to lookup a value, if the class contains the value then use it and modify a property of the class. I am concerned about the design of the public interface.
Here is how the class is going to be used:
ClassItem *pClassItem = myClass.Lookup(value);
if (pClassItem)
{ // item is found in class so modify and use it
pClassItem->SetAttribute(something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However I don't want to have to expose ClassItem to this client (ClassItem is an implementation detail of MyClass).
To get round that the following could be considered:
bool found = myClass.Lookup(value);
if (found)
{ // item is found in class so modify and use it
myClass.ModifyAttribute(value, something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However this is inefficient as Modify will have to do the lookup again. This would suggest a lookupAndModify type of method:
bool found = myClass.LookupAndModify(value, something);
if (found)
{ // item is found in class
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
But rolling LookupAndModify into one method seems like very poor design. It also only modifies if value is found and so the name is not only cumbersome but misleading as well.
Is there another better design that gets round this issue? Any design patterns for this (I couldn't find anything through google)?
Actually std::set<>::insert() does precisely this. If the value exists, it returns the iterator pointing to the existing item. Otherwise, the iterator where the insertion was made is returned.
It is likely that you are using a similar data structure for fast lookups anyway, so a clean public interface (calling site) will be:
myClass.SetAttribute(value, something)
which always does the right thing. MyClass handles the internal plumbing and clients don't worry about whether the value exists.
Two things.
The first solution is close.
Don't however, return ClassItem *. Return an "opaque object". An integer index or other hash code that's opaque (meaningless) to the client, but usable by the myClass instance.
Then lookup returns an index, which modify can subsequently use.
void *index = myClass.lookup( value );
if( index ) {
myClass.modify( index, value );
}
else {
myClass.add( value );
}
After writing the "primitive" Lookup, Modify and Add, then write your own composite operations built around these primitives.
Write a LookupAndModify, TryModify, AddIfNotExists and other methods built from your lower-level pieces.
This assumes that you're setting value to the same "something" in both the Modify and Add cases:
if (!myClass.AddIfNotExists(value, something)) {
// use myClass
}
Otherwise:
if (myClass.TryModify(value, something)) {
// use myClass
} else {
myClass.Add(value, otherSomething);
}