Default Argument Not Permitted in a Tuple Type When Defining Function Type

Is it possible to have parameters that aren't used as arguments?

You (everyone, really) would really benefit from reading the Swift book, cover to cover.

What you're looking for is called a default value.

func test(paramA: String = "Your default value here") {}

or

func test(paramA: String? = nil) {}

The former is simpler, but more limited. For example, you can't distinguish rather the default value "Your default value here" was used, or whether the caller passed in their own value, which happens to be "Your default value here"). In my experience, the distinction is seldom required, but it's good to call out just in case.

In the latter case, you have the flexibility to handle the optional in many more ways. You could substitute a default value with ??, do conditional binding, map it, etc.

Swift func signature and default parameter values syntax?

The following radar:

  • https://github.com/lionheart/openradar-mirror/issues/12160
  • http://www.openradar.me/18041799

Was marked as fixed in the following validation test:

  • swift/validation-test/compiler_crashers_fixed/00023-getcallerdefaultarg.swift
// Test case submitted to project by https://github.com/practicalswift (practicalswift)
// http://www.openradar.me/18041799
// https://gist.github.com/stigi/336a9851cd80fdef22ed
func a(b: Int = 0) {
}
let c = a
c() // expected-error {{missing argument for parameter #1 in call}}

Based on the validation test above (particularly the expected error), I believe calling a function via a stored reference to it (e.g. L.ws[0] in your example) will not allow omitting arguments even if the function pointed to supplies default parameter values for these omitted arguments.

The type of the c stored closure (/function reference) above will be inferred to as (Int) -> (), and will contain no information regarding default parameter values. When attempting to call c as if it were a closure/function pointer of type () - > (), the missing argument error will be prompted without any possibility of tapping into the compiler magic that works when directly calling a function (not via a stored reference/closure to it!) that, in itself, allows omitting arguments for parameters with default values.

Optional arguments in completionHandler

The compiler error is misleading. It has nothing to do with tuples. Here is how to provide default closure value. Define your function like this:

func firstFunc(completionHandler:(([String:AnyObject]) -> Void?) = { _ in return }) {
}

{ _ in return } is the default value there. This is what will work now:

firstFunc() // uses default closure value

firstFunc { (completionHandler: [String : AnyObject]) -> Void? in
return
}

Type for Optional Method Argument of Generic Class

With some trickery, you can make this work. The recipe includes:

  1. never as the default type for the generic type parameter
  2. rest parameters with tuple types added in TS 3.0

The idea is to conditionally switch between an empty tuple and a tuple of one argument (or more, or several conditions - go wild depending on your implementation). Here is how this would look like:

class ClassA<MyGenericType = never> {
public methodWithGenericArgument(...args: MyGenericType extends never ? [] : [MyGenericType]): void {
// Do smth
}
}

type NotOptionalArgumentType = number;

const instanceX = new ClassA();
instanceX.methodWithGenericArgument(); // OK
instanceX.methodWithGenericArgument(15); // ERROR

const instanceY = new ClassA<NotOptionalArgumentType>();
instanceY.methodWithGenericArgument(); // ERROR
instanceY.methodWithGenericArgument(15); // OK

let argumentValue!: NotOptionalArgumentType;
const instanceZ = new ClassA<NotOptionalArgumentType>();
instanceZ.methodWithGenericArgument(); // ERROR
instanceZ.methodWithGenericArgument(argumentValue); // OK

Playground

Python default values for tuple in function arguments

This is a much more managable solution than the currently accepted one. It will give you the ease of declaring your default args as tuples instead of declaring each value's names in the function signature. (Imagine doing that for a 4x4 matrix!)

update:

You can do:

def func(self, args):
defaultargs = (1, 2, 3)
args = tuple(map(lambda x, y: y if y is not None else x, defaultargs, args))

In this case, instead of having the default args in the function definition, you can have it inside and do an or operation on each element as shown. This way, any positions that were left blank in the args would be filled by the respective positions from the default args tuple.

This solves the caveat mentioned in the comment below.



Related Topics



Leave a reply



Submit