6

I assume that Dart doesn't allow for both named and optional positional parameters. Am I correct in assuming this? Is there a way that I can create this function without having to use a named parameter for the second string?

Here is my function:

void log(Object? s,{ int priority = 1,LogType logType = LogType.misc,bool on = true}){
  if (priority >= lowestDisplayedPriority && (activeLogs.contains(logType)) && on){
    print('='+s.toString());
  }
}

I want to turn the function into the following:

void log(Object? s,[Object? s2 = ''],{ int priority = 1,LogType logType = LogType.misc,bool on = true}){
  if (priority >= lowestDisplayedPriority && (activeLogs.contains(logType)) && on){
    print('='+s.toString());
    if(s2 != ''){
      print('='+s2.toString());
    }  
  }
}

I get an error which says "Expected to find ')'."

My desired function's usage would be something like this:

log(A,B, priority : 2) or log(A, priority : 2)

4
  • If you called log(A,B), how is it to know if B is an s2 or a priority? Commented Mar 22, 2023 at 13:57
  • An example would be log(A,B, priority : 2) or log(A, priority : 2) Commented Mar 22, 2023 at 14:08
  • 1
    It's not currently possible to have both named and optional positional parameters. See: github.com/dart-lang/language/issues/1076 Commented Mar 22, 2023 at 15:06
  • @ScottHunter There would be no ambiguity. For log(A, B), B is positional and not named and therefore would be s2. Unlike Python, parameters are positional or named, never both. Arguments for named parameters must always be named. Commented Mar 22, 2023 at 15:15

2 Answers 2

4

That's not yet possible. Please keep upvoting https://github.com/dart-lang/language/issues/1076

Two alternatives came to mind you could use today:

Use a list as first parameter

This way you always have to provide a list, which sucks for single arguments. But it works quite well.

void main() {
  log([1, 2], priority: Priority.low);
  log(['a', 'b', 'c'], priority: Priority.high);
  log(['hello']);
  // low: 1, 2
  // high: a, b, c
  // low: hello
}


void log(List<Object?> args, {Priority priority = Priority.low}) {
  final text = args.join(', ');
  print('${priority.name}: $text');
}

enum Priority {
  low,
  high,
}

Filter special types from args as options

This doesn't give you named parameters, but it might be easier to call for single arguments.

import 'package:collection/collection.dart';

void main() {
  log(1, 2, Priority.low);
  log('a', 'b', 'c', Priority.high);
  log('hello');
  // low: 1, 2
  // high: a, b, c
  // low: hello
}

void log([
  Object a0 = _default,
  Object a1 = _default,
  Object a2 = _default,
  Object a3 = _default,
]) {
  final allArgs = [a0, a1, a2, a3].where((it) => it != _default);
  final priority = allArgs.whereType<Priority>().firstOrNull ?? Priority.low;
  final text = allArgs.where((it) => it is! Priority).join(', ');

  print('${priority.name}: $text');
}

enum Priority {
  low,
  high,
}

const Object _default = Object();
Sign up to request clarification or add additional context in comments.

1 Comment

This will definitely achieve my intended functionality. Thank you.
0

@jamerdlin Answered my question. It is not currently possible (2023/03/22).

My solution is to create another function to let take in a List<Object?> where I can print multiple things when needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.