Sebastian
Sebastian

Reputation: 8164

Write a custom access operator in Swift

I implemented a helper to have an array of unowned references:

class Unowned<T: AnyObject>
{        
    unowned var value : T    

    init (value: T) { self.value = value }
    func get() -> T { return self.value }
}

Now, it is possible to do [ Unowned<Foo> ]. However, I'm not satisfied with having the additional get() method to retrieve the underlying object. So, I wanted to write a custom binary operator, e.g. --> for being able to do

for unownedFoo in ArrayOfUnownedFoos
{
    var bar : Int = unownedFoo-->method()
}

My current approach is to define

infix operator --> { }
func --><T> (inout lhs: Unowned<T>, inout rhs: () -> Int) -> Int
{
}

The idea I had behind this is:

  1. lhs is obvisouly the object I get out of the array, on which I want to perform the call on
  2. rhs is the method I desire to call. In this case method() would not take no parameters and return an Int, and therefore
  3. The return value is int.

However, the following problems / uncertainties arise:

  1. Is this the correct approach?
  2. Are my assumptions above correct?
  3. How can I call the provided closure rhs on the instance of the extracted Unowned<T>, e.g. (pseudocode) lhs.value.rhs(). If method() was static, I could do T.method(lhs.value), but then I would have to extract the name of the method somehow to make it more generic.

Upvotes: 0

Views: 141

Answers (2)

rintaro
rintaro

Reputation: 51911

Maybe, a postfix operator is rather simple.

postfix operator * {}

postfix func *<T>(v:Unowned<T>) -> T {
    return v.value
}

// Usage:
for unownedFoo in ArrayOfUnownedFoos {
    var bar : Int = unownedFoo*.method()
}

Upvotes: 1

GoZoner
GoZoner

Reputation: 70145

Use something like:

func --> <T:AnyObject, V> (lhs: Unowned<T>, rhs: (T) -> V) -> V
{
   return rhs (lhs.get())
}

and then use it as:

for unownedFoo in ArrayOfUnownedFoos
{
    var bar : Int = unownedFoo-->{ (val:Int) in return 2*val }
}

Specifically, you don't want to use method() as that itself is a function call - which you probably don't want unless method() is actually returning a closure.

Upvotes: 1

Related Questions