Understanding enum and function signature - macos

In learning Swift, I came across this code: -
enum ServerResponse {
case Result(String, String)
case Error(String)
}
for i in 1...10{
let mySuccess: ServerResponse = {
let zeroOrOne = rand() % 2
if zeroOrOne == 0 {
return ServerResponse.Result("7:00 am", "8.09 pm")
} else {
return ServerResponse.Error("Out of cheese.")
}
}()
var serverResponse: String
switch mySuccess {
case let .Result(sunrise, sunset):
serverResponse = "Sunrise is at \(sunrise) and sunset as \(sunset)"
case let .Error(error):
serverResponse = "Failure... \(error)"
}
println(serverResponse)
}
As can be seen here, there are parentheses () after the closing end brace of the declaration for:
let mySuccess: ServerResponse = {
...
}()
Without the parenthesis, playground produces the error:-
Function produces expected type 'ServerResponse'; did you mean to call it with ()?
Considering a function has the signature: -
func name(param) -> returnType
Can someone please explain why the parenthesis are required here? Is it a form of minimised closure, or something else?

It's an anonymous function/lambda/closure (however you want to call it exactly), taking no argument, and whose return type is inferred by the compiler, which is then called immediately. It's similar to (function() {…})() in JavaScript.
It has the big advantage of allowing you to define mySuccess as a constant instead of a variable. Additionally, it creates a scope, such that intermediary variables (like zeroOrOne) are not visible outside.
What I'm wondering is just why the author of this code didn't use the same style to define and assign serverResponse…

Your ServerResponse is not a function, it is an enum, but without the parentheses the block you would be trying to assign to mySuccess IS a function (that returns a ServerResponse), and therefore cannot be assigned to a ServerResponse. The result of calling the function (adding the parentheses) can be.

Related

Golang - Cannot infer T from interface implementation? [duplicate]

This question already has an answer here:
cannot infer V: infer type parameter from constraint implementation
(1 answer)
Closed 5 months ago.
Say I have the following code:
type Getter[T any] interface {
Get() T
}
type Wrapper[T any] struct {
a T
}
func (s Wrapper[T]) Get() T {
return s.a
}
Here, you can say that Wrapper[T] implements Getter[T] - since it implements Get() T which is the only requirement.
Now, I have a function that needs to take a Getter[T] in order to return the internal value...
func Return[T any](i Getter[T]) T {
return i.Get()
}
var s1 = Wrapper[int]{
a: 5,
}
Here, Return just gets the value inside - so the expectation is that when I pass in s1, I should get 5 in return.
var s2 = Return(s1) // type Wrapper[int] of s1 does not match Getter[T] (cannot infer T)
...instead, I get that error. Now, there is an easy workaround here...
func (s Wrapper[T]) Getter() Getter[T] {
return s
}
var s2 = Return(s1.Getter())
This ends up working. Getter() does nothing but return itself - functionally speaking, s1 and s1.Getter() should be identical here - and yet it doesn't work. T can be inferred in the method, but not as a parameter.
My question is this: Am I doing something wrong here - or is this just a part of Go? For this example to work, do I need to add a dummy method just to help the compiler - or am I missing something?
You do not need to add methods to Wrapper, but if type inference does not succeed (the compiler can't infer all types), you have to provide the types for the type parameters explicitly, like this:
var s2 = Return[int](s1)
The Return() function has a type parameter, if you provide the type for T explicitly (int here), then the compiler will be able to validate that s1 does indeed implement the Getter[int] interface. Try it on the Go Playground.

RxSwift Subscribing on ControlEvent

The first observable fires, but the second does not. What gives? I switched the events in the block i.e print($0) in the second bloack and vice-versa, then the first does not work, but the second works. What is it about $0 versus a regular string that makes the observable observe?
let someObservable = self.inputButton!.rx.tap.subscribe(){
print($0)
}
let someObservable1 = self.inputButton!.rx.tap.subscribe(){
print("Hello")
}
In the first one, you are using the $0, which is the first argument that is passed to the closure that you've provided.
let someObservable = self.inputButton!.rx.tap.subscribe(){
print($0)
}
In this case the compiler decides that you are actually calling the following function, because it matches that what you are using, i.e. it expects one nameless argument, which in turn is a closure with one argument, the event:
func subscribe(_ on: #escaping (Event<E>) -> Void)
You can rewrite your first code like this:
let someObservable = self.inputButton!.rx.tap.subscribe() { event in
print(event)
}
Now, in the second one you are providing a closure, that doesn't use any passed arguments. So the compiler has to find another function that would be syntactically valid at this point. As a matter of fact it will use this one for you:
func subscribe(file: String = #file, line: UInt = #line, function: String = #function, onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
All of this function's arguments have default values and you can ignore all of them. The last argument onDispose is of closure type and can be written with the trailing closure notation. That means that the closure that you pass here:
let someObservable1 = self.inputButton!.rx.tap.subscribe(){
print("Hello")
}
will be used as your dispose block.
Rule of thumb when using RxSwift:
Be explicit, name your arguments, provide the types of your arguments, in the long run you will spare a lot more time!

How to get an enumeration's value's value?

In Apple's "A swift Tour" they have this code snippet:
enum OptionalValue<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)
How would you get the 100? You can't do possibleInteger == 100 to test if possibleInteger has the value 100 inside. I know you can put functions inside enumerations, but you can't have variables. Maybe I'm understanding enumerations wrong…
If I command click Optional when declaring an optional (var x:Optional<Int>), I can find
enum Optional<T> : Reflectable, NilLiteralConvertible {
case None
case Some(T)
init()
init(_ some: T)
/// Haskell's fmap, which was mis-named
func map<U>(f: (T) -> U) -> U?
func getMirror() -> MirrorType
static func convertFromNilLiteral() -> T?
}
But I do not understand what any of that means. Help?
You can use a switch statement to get the value, as described here. Relevant bit:
... the associated values can be extracted as part of the switch
statement. You extract each associated value as a constant (with the
let prefix) or a variable (with the var prefix) for use within the
switch case’s body:
For your case, you'd want something like:
switch possibleInteger {
case .Some(let value):
println(value)
case .None:
println("<None>")
}

calling method from struct in swift

I found what looks like an elegant solution to iterating over enums here: How to enumerate an enum with String type?
Next, I'm having trouble figuring out how to call this method. At face value, it doesn't look like it takes an argument, but when I try to call Card.createDeck() I get a compiler error telling me "error: missing argument for parameter #1 in call".
Please let me know what I'm doing wrong here? What am I supposed to pass to this method?
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
func createDeck() -> [Card] {
var deck = [Card]()
var n = 1
while let rank = Rank.fromRaw(n) {
var m = 1
while let suit = Suit.fromRaw(m) {
deck += Card(rank: rank, suit: suit)
m++
}
n++
}
return deck
}
}
createDeck() is a instance method. Doing Card.createDeck() is a call to a class method that doesn't exist.
class func - for class methods
Edit:
I misread that it was a struct, but the same logic applies.
static func - for static methods
You can not able to call it directly as you need instace of struct as it is not class function.So use
Card(rank:Rank.yourRank,suit:Suit.yourSuit).createDeck()
Actually to make struct you need rank and suit instance so first make them and than pass to Card constructor.By default struct have arguments as their properties.

Pass a result from multi-returing function to another one taking only one argument in Go

Is it possible to pass a result form function which returns multiple values directly to function which accepts only one? Example:
func MarshallCommandMap(mapToMarshall map[string]string) string {
return string(json.Marshal(mapToMarshall))
}
The example above will cause compilation error:multiple-value json.Marshal() in single-value context. I know it is possible to get same result with additional variable:
func MarshallCommandMap(mapToMarshall map[string]string) string {
marshaledBytes, marshalingError := json.Marshal(mapToMarshall)
if (marshalingError != nil) {
panic(marshalingError)
}
return string(marshaledBytes)
}
But is it possible to pass only first value direclty without any variable?
I think you mean doing something like python's tuple unpacking.
Unfortunately this is not possible in Go (AFAIK).
No you can't, however 2 things with your code.
Shouldn't panic, either return an error or return an empty string.
You can make it shorter.
Example :
func MarshallCommandMap(mapToMarshall map[string]string) string {
js, _ := json.Marshal(mapToMarshall) //ignore the error
return string(js)
}

Resources