Giter Site home page Giter Site logo

passsy / kt.dart Goto Github PK

View Code? Open in Web Editor NEW
467.0 9.0 30.0 1.21 MB

A port of kotlin-stdlib for Dart/Flutter including immutable collections (KtList, KtMap, KtSet) and other packages

License: Apache License 2.0

Dart 99.79% Shell 0.21%
dart collection kotlin flutter dartlang hacktoberfest

kt.dart's Introduction

kt.dart

Pub codecov

This project is a port of Kotlin's Kotlin Standard library for Dart/Flutter projects. It's a useful addition to dart:core and includes collections (KtList, KtMap, KtSet) as well as other packages which can improve every Dart/Flutter app.

dependencies: 
  kt_dart: ^1.1.0
import 'package:kt_dart/kt.dart';

Motivation

Dart's dart:core package provides basic building blocks. But sometimes they are too low level and not as straightforward as Kotlin's kotlin-stdlib.

Here are a few examples of what this project offers: (click to expand)

Immutable collections by default

dart:core collections

Dart's List is mutable by default. The immutable List.unmodifiable is the same type, but the mutation methods throw at runtime.

final dartList = [1, 2, 3];
dartList.add(4); // mutation is by default possible
assert(dartList.length == 4);

final immutableDartList = List.unmodifiable(dartList);
immutableDartList.add(5); // throws: Unsupported operation: Cannot add to an unmodifiable list

Dart's mutable List is indistinguishable from an immutable List which might cause errors.

void addDevice(List<Widget> widgets, Device device) {
  // no way to check whether widgets is mutable or not
  // add might or might now throw
  widgets.add(_deviceRow());
  widgets.add(Divider(height: 1.0));
}

kt_dart collections

KtList and KtMutableList are two different Types. KtList is immutable by default and has no mutation methods (such as add). Methods like map((T)->R) or plusElement(T) return a new KtList leaving the old one unmodified.

final ktList = listOf(1, 2, 3);
// The method 'add' isn't defined for the class 'KtList<int>'.
ktList.add(4); // compilation error
       ^^^

// Adding an item returns a new KtList
final mutatedList = ktList.plusElement(4);
assert(ktList.size == 3);
assert(mutatedList.size == 4);

KtMutableList offers mutation methods where the content of that collection can be actually mutated. I.e. with remove(T) or add(T);

// KtMutableList allow mutation
final mutableKtList = mutableListOf(1, 2, 3);
mutableKtList.add(4); // works!
assert(mutableKtList.size == 4);

All collection types have mutable counterparts:

Immutable Mutable
KtList KtMutableList
KtSet KtMutableSet, KtHashSet, KtLinkedSet
KtMap KtMutableMap, KtHashMap, KtLinkedMap
KtCollection KtMutableCollection and all the above
KtIterable KtMutableIterable and all the above
Deep equals

dart:core collections

Dart's List works like a Array in Java. Equals doesn't compare the items; it only checks the identity. To compare the contents you have to use helper methods methods from 'package:collection/collection.dart'.

// Comparing two Dart Lists works only by identity
final a = [1, 2, 3, 4];
final b = [1, 2, 3, 4];
print(a == b); // false, huh?

// Content-based comparisons require unnecessary glue code
Function listEq = const ListEquality().equals;
print(listEq(a, b)); // true

// MapEquality isn't deep by default
final x = {1: ["a", "b", "c"], 2: ["xx", "yy", "zz"]};
final y = {1: ["a", "b", "c"], 2: ["xx", "yy", "zz"]};
Function mapEq = const MapEquality().equals;
print(mapEq(x, y)); // false, wtf?!

Function deepEq = const DeepCollectionEquality().equals;
print(deepEq(x, y)); // true, finally

kt_dart collections

KtList and all other collection types implement equals by deeply comparing all items.

final a = listOf(1, 2, 3, 4);
final b = listOf(1, 2, 3, 4);
print(a == b); // true, as expected

final x = mapFrom({1: listOf("a", "b", "c"), 2: listOf("xx", "yy", "zz")});
final y = mapFrom({1: listOf("a", "b", "c"), 2: listOf("xx", "yy", "zz")});
print(x == y); // deep equals by default
Common methods

Some of Dart's method names feel unfamiliar. That's because modern languages and frameworks (Kotlin, Swift, TypeScript, ReactiveExtensions) kind of agreed on naming methods when it comes to collections. This makes it easy to switch platforms and discuss implementations with coworkers working with a different language.

expand -> flatMap

final dList = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
final kList = listOf(listOf(1, 2, 3), listOf(4, 5, 6), listOf(7, 8, 9));

// dart:core
final dFlat = dList.expand((l) => l).toList();
print(dFlat); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

// kt_dart
final kFlat = kList.flatMap((l) => l);
print(kFlat); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

where -> filter

final dNames = ["Chet", "Tor", "Romain", "Jake", "Dianne"];
final kNames = listFrom(dNames);

// dart:core
final dShortNames = dNames.where((name) => name.length <= 4).toList();
print(dShortNames); // [Chet, Tor, Jake]

// kt_dart
final kShortNames = kNames.filter((name) => name.length <= 4);
print(kShortNames); // [Chet, Tor, Jake]

firstWhere -> first, firstOrNull

final dNames = ["Chet", "Tor", "Romain", "Jake", "Dianne"];
final kNames = listFrom(dNames);

// dart:core
dNames.firstWhere((name) => name.contains("k")); // Jake
dNames.firstWhere((name) => name.contains("x"), orElse: () => null); // null
dNames.firstWhere((name) => name.contains("x"), orElse: () => "Nobody"); // Nobody

// kt_dart
kNames.first((name) => name.contains("k")); // Jake
kNames.firstOrNull((name) => name.contains("x")); // null
kNames.firstOrNull((name) => name.contains("x")) ?? "Nobody"; // Nobody

KtList

KtList is a read-only list of elements. It is immutable because it doesn't offer mutation methods such as remove or add. Use KtMutableMap if you want to use a mutable list.

To create a KtList/KtMutableList use the KtList.of constructor or convert an existing Dart List to a KtList with the list.toImmutableList() extension.

Create a KtList

// Create a KtList from scratch
final beatles = KtList.of("John", "Paul", "George", "Ringo");

// Convert a existing List to KtList
final abba = ["Agnetha", "Björn", "Benny", "Anni-Frid"];
final immutableAbba = abba.toImmutableList();

Create a KtMutableList

KtList is immutable by default, which means it doesn't offer methods like add or remove. To create mutable list with kt_dart use the KtMutableList constructor.

// Create a KtMutableList from scratch
final beatles = KtMutableList.of("John", "Paul", "George", "Ringo");
beatles.removeAt(0);
print(beatles); // [Paul, George, Ringo]

Mutable/Immutable conversion

Conversions between KtList and KtMutableList can be done with KtList.toMutableList() and KtMutableList.toList();

final beatles = KtList.of("John", "Paul", "George", "Ringo");
final mutable = beatles.toMutableList();
mutable.removeAt(0);
print(mutable); // [Paul, George, Ringo]
print(beatles); // [John, Paul, George, Ringo]

for loop

kt_dart collections do not implement Iterable. It is therefore not possible to directly iterate over the entries of a KtList.

All kt_dart collections offer a .iter property which exposes a Dart Iterable. For-loops therefore don't look much different.

final beatles = KtList.of("John", "Paul", "George", "Ringo");
for (final member in beatles.iter) {
  print(member);
}

Yes, alternatively you could use .asList() instead which returns a Dart List.

Kotlin syntax

Kotlin users might be more familiar with the listOf() and mutableListOf() functions. Use them if you like but keep in mind that the dart community is much more used to use constructors instead of top-level functions.

final beatles = listOf("John", "Paul", "George", "Ringo");
final abba = mutableListOf("Agnetha", "Björn", "Benny", "Anni-Frid");

KtSet

A KtSet is a unordered collection of elements without duplicates.

Creating a KtSet/KtMutableSet is very similar to the KtList API.

// Create a KtSet from scratch
final beatles = KtSet.of("John", "Paul", "George", "Ringo");

// Convert a existing Set to KtSet
final abba = {"Agnetha", "Björn", "Benny", "Anni-Frid"};
final immutableAbba = abba.toImmutableSet();

KtMap

To create a KtMap/KtMutableMap start with Dart Map and then convert it to a KtMap with either:

  • pokemon.toImmutableMap(): KtMap (since Dart 2.7)
  • KtMap.from(pokemon): KtMap
  • pokemon.kt: KtMutableMap (since Dart 2.7)
  • KtMutableMap.from(pokemon): KtMutableMap
// immutable
final pokemon = {
  1: "Bulbasaur",
  2: "Ivysaur",
  3: "Stegosaur",
}.toImmutableMap();

final newPokemon = KtMap.from({
  152: "Chikorita",
  153: "Bayleef",
  154: "Meganium",
});

// mutable
final mutablePokemon = {
  1: "Bulbasaur",
  2: "Ivysaur",
  3: "Stegosaur",
}.kt;

final newMutablePokemon = KtMutableMap.from({
  152: "Chikorita",
  153: "Bayleef",
  154: "Meganium",
});

KtHashMap and KtLinkedMap

You may want to use a specific Map implementation. kt_dart offers:

  • KtLinkedMap - based on Darts LinkedHashMap where the insertion order of keys is remembered and keys are iterated in the order they were inserted into the map
  • KtHashMap - based on Darts HashMap where keys of a HashMap must have consistent [Object.==] and [Object.hashCode] implementations. Iterating the map's keys, values or entries (through [forEach]) may happen in any order.

KtPair, KtTriple

kt_dart offer two types of tuples, KtPair with two elements and KtTriple with three elements. They are used by some collection APIs and prevent a 3rd party dependency.

final beatles = KtList.of("John", "Paul", "George", "Ringo");
final partitions = beatles.partition((it) => it.contains("n"));
print(partitions.first); // [John, Ringo]
print(partitions.second); // [Paul, George]

There won't be a KtQuadruple or TupleN in this library. If you want to use tuples heavily in you application consider using the tuple package. Better, use freezed to generated data classes which makes for a much better API.

Annotations

@nullable

Kotlin already has Non-Nullable types, something which is coming to Dart soon™. kt_dart already makes use of Non-Nullable Types and never returns null unless a method is annotated with @nullable.

/// Returns the value corresponding to the given [key], or `null` if such a key is not present in the map.
@nullable
V get(K key);

There isn't any tooling which will warn you about the wrong usage but at least it's documented. And once nnbd lands in Dart it will be fairly easy to convert.

@nonNull

This annotation annotates methods which never return null. Although this is the default in kt_dart, is makes it very obvious for methods which sometimes return null in other languages.

@experimental

A method/class annotated with @experimental marks the method/class as experimental feature. Experimental APIs can be changed or removed at any time.

License

Copyright 2019 Pascal Welsch

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

kt.dart's People

Contributors

acherkashyn avatar anas35 avatar davidmartos96 avatar dev-dfm avatar gieted avatar hugobrancowb avatar jeroen-meijer avatar marciokuroki avatar matthaiossait avatar nohli avatar passsy avatar psygo avatar redbrogdon avatar rishabh-negi avatar robiness avatar timwhiting avatar triallax avatar votruk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kt.dart's Issues

KtMap.map(MapEntry<K, V> -> R) : KtList<R>

Kotlin allows mapping of entries in a map using .map

mapOf(1 to "foo", 2 to "bar")
        .map { "${it.key} -> ${it.value}" }
        .forEach(::print)
// 1 -> foo
// 2 -> bar

This leads to a name clash with KtMap.map which returns the Dart Map.

Currently all kt.dart collections allow access to the dart equivalents.

KtIterable.iter -> Iterable
KtList.list -> List
KtMap.map -> Map
KtSet.set -> Set

We have to find a way to provide standardized ways to access the dart equivalents. Additionally we should make it as easy as possible to make kt.dart collections useable using for loops.

// kt.dart 0.5.0
for(final i in listOf(1, 2, 3).iter) {
  print(i);
}

Sorting by an int, double etc

I get a compilation error when trying to sort by a property for a int, double, etc:

listOf(1, 2, 3).sortedBy((n) => n);

The compiler error is:

error: Couldn't infer type parameter 'R extends Comparable<R>'.

Tried to infer 'int' for 'R extends Comparable<R>' which doesn't work:
  Type parameter 'R extends Comparable<R>' declared to extend 'Comparable<int>'.
The type 'int' was inferred from:
  Parameter 'selector' declared as     'R Function(int)'
                       but argument is 'int Function(int)'.

Consider passing explicit type argument(s) to the generic.

Could this be fixed by changing the generic parameter bound to R extends Comparable?

Shuffle

I develop an app that involves massive working with lists. One of the popular features that I use is list shuffling.

As I see there is no such a method in this library yet. It is very frustrating to switch to standard dart collections to just shuffle and then go back to kt.dart which is awesome btw.

Do you have plans to implement this functionality?

Add `@useResult` to methods

Methods like plusElement and minusElement return a new list and don't change the existing list (like add and remove of a normal List).

To help users to not forget using the new list, we could add @useResult.

filterNotNull() doesn't change type to non nullable list

I have the following scenario.

Actual:
I get a KtList<T?> objects
I run the following code final KtList<T> nonNullObjects = objects.filterNotNull();

The dart type check still requires me to use a nullable T? type instead of a non-nullable one

Expect:
filterNotNull() also changes the returned type to T and doesn't require me to continue working with T?

Annotate TODO with @alwaysThrows

Adding the @alwaysThrows annotation allows the analyzer to better understand the control flow. It then doesn't report "missing_returns" when a function ends with TODO();

The signature of mapNotNull is wrong.

Problem

extension RequireNoNullsKtIterableExtension<T> on KtIterable<T?> {

/// Returns a list containing the results of applying the given [transform] function
/// to each element in the original collection.
KtList<R> mapNotNull<R>(R? Function(T?) transform) {
final mapped = mapNotNullTo(mutableListOf<R>(), transform);
// TODO ping dort-lang/sdk team to check type bug
// When in single line: type "DartMutableList<String>' is not a subtype of type 'Null"
return mapped;
}
/// Applies the given [transform] function to each element in the original collection
/// and appends only the non-null results to the given [destination].
C mapNotNullTo<R, C extends KtMutableCollection<R>>(
C destination, R? Function(T?) transform) {
for (final item in iter) {
final result = transform(item);
if (result != null) {
destination.add(result);
}
}
return destination;
}
}

This causes a build error with the following code:

      listOf("not null").mapNotNull((it) => it.startsWith("not") ? it : null); // error!!
      listOf("not null", null).mapNotNull((it) => it?.startsWith("not") == true ? it : null);

The following code in Kotlin did not cause a build error .

        listOf("not null").mapNotNull { if (it.startsWith("not")) it else null }
        listOf("not null", null).mapNotNull { if (it?.startsWith("not") == true) it else null }

It looks like the signature of RequireNoNullsKtIterableExtension.mapNotNull is wrong.

Suggestion

Quoting the implementation of mapNotNull from kotlin.collections:

/**
 * Returns a list containing only the non-null results of applying the given [transform] function
 * to each element in the original collection.
 * 
 * @sample samples.collections.Collections.Transformations.mapNotNull
 */
public inline fun <T, R : Any> Iterable<T>.mapNotNull(transform: (T) -> R?): List<R> {
    return mapNotNullTo(ArrayList<R>(), transform)
}

/**
 * Applies the given [transform] function to each element in the original collection
 * and appends only the non-null results to the given [destination].
 */
public inline fun <T, R : Any, C : MutableCollection<in R>> Iterable<T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
    forEach { element -> transform(element)?.let { destination.add(it) } }
    return destination
}

The following code seems fine.

extension _<T> on KtIterable<T> {
  /// Returns a list containing the results of applying the given [transform] function
  /// to each element in the original collection.
  KtList<R> mapNotNull2<R>(R? Function(T) transform) {
    final mapped = mapNotNullTo(mutableListOf<R>(), transform);
    // TODO ping dort-lang/sdk team to check type bug
    // When in single line: type "DartMutableList<String>' is not a subtype of type 'Null"
    return mapped;
  }

  /// Applies the given [transform] function to each element in the original collection
  /// and appends only the non-null results to the given [destination].
  C mapNotNullTo<R, C extends KtMutableCollection<R>>(C destination, R? Function(T) transform) {
    for (final item in iter) {
      final result = transform(item);
      if (result != null) {
        destination.add(result);
      }
    }
    return destination;
  }
}

Note that the code above is an extension of KtIterable<T>.

I thought mapNotNull should be defined in
extension KtIterableExtensions<T> on KtIterable<T> or
extension ChainableKtIterableExtensions<T> on KtIterable<T>.

Version

This problem happened when I upgraded from 0.9.1 to 1.0.0.

   kt_dart: ^0.9.1 -> ^1.0.0

Question about KtList

In the docs there's this:

kt_dart collections do not implement Iterable. It is therefore not possible to directly iterate over the entries of a KtList.

But there package also exposes a iterator via .iter property as shown in the example.
So here comes my question, is there a reason for kt.dart not to implement Iteratable?

Snapshot release

master contains bugfixes which aren't released yet. How can I include them in my project? Does this project support SNAPSHOT releases?

Prefer const constructors

There are a couple of places that you can add const constructors, mainly with empty sets, maps, and lists. I'll submit a pull request with a few I was able to find. The good thing about const constructors is they can be used as defaults for parameters, which reduces the worry about nullability of optional parameters.

groupByTransform(_).getOrDefault(_, KtList.empty()) crashes always

As groupByTransform directly casts KtMutableMap,KtMutableList to KtMap,KtList. when getOrDefault(key, KtList.empty()) is used on returned map from groupByTransform. It crashes with error type 'EmptyList<Currency>' is not a subtype of type 'KtMutableList<Currency>' of 'defaultValue'

Reproducible code

main() {
  var usd = Currency(1, "USD");
  var inr = Currency(2, "INR");
  KtList<Currency> currency = listOf(usd, inr);
  KtList<CurrencyConversionData> conversion =
      listOf(CurrencyConversionData(1, 2));
  KtMap<Currency, KtList<Currency>> conversions =
      _toCurrencyMap(conversion, currency);

  print(conversions.getOrDefault(Currency(1, "USD"), KtList.empty())); // CRASH HERE (type 'EmptyList<Currency>' is not a subtype of type 'KtMutableList<Currency>' of 'defaultValue')
}

KtMap<Currency, KtList<Currency>> _toCurrencyMap(
    KtList<CurrencyConversionData> conversion, KtList<Currency> currency) {
  KtMap<int, Currency> currencyMap = currency.associateBy((cur) => cur.id);
  return conversion.groupByTransform(
    (conv) => currencyMap.get(conv.fromRef)!,
    (conv) => currencyMap.get(conv.toRef)!,
  );
}

class Currency {
  final int id;
  final String ticker;

  Currency(this.id, this.ticker);
}

class CurrencyConversionData {
  final int fromRef;
  final int toRef;

  CurrencyConversionData(this.fromRef, this.toRef);
}

KtList.list returning null elements only

Hi, is there any function in KtList which returns elements as dart List? I tried using KtList.list but its returning null values only with same size list as the original one. Is this an intended behavior or am I missing something? Attached is screenshot of debugging session.

image

KMutableEntry.setValue doesn't change value in collection

KMutableEntry.setValue doesn't change the underlying collection. Here is a valid test which is currently failing

final pokemon = mutableMapOf({
  1: "Bulbasaur",
  2: "Ivysaur",
});

pokemon.entries.forEach((entry) {
  entry.setValue(entry.value.toUpperCase());
});

// throws because pokemon is unchanged
expect(
    pokemon,
    mapOf({
      1: "BULBASAUR",
      2: "IVYSAUR",
    }));

Consider renaming to kt.dart

kotlin.dart might not be the best choice. It depends on JetBrains good-will not to file a lawsuit against this project.

Considerable options are:

  • kt.dart

Mutable collection classes should not implement their immutable counterparts

Example of why I think this is bad behavior:

final mutableList = mutableListOf(1, 2, 3);
final KtList<int> immutableList = mutableList;
mutableList[0] = 0;
print(immutableList); // Prints [0, 2, 3]!

I think this breaks the expectation that immutable collections should never change, which might cause some bugs.

I'd be happy to open a PR, although I imagine such a large breaking change would require a new major version.

KMutableIterator.remove() doesn't remove item from collection

var abc = mutableListOf(["a", "b", "c"]);
final KMutableIterator<String> i = abc.iterator();
assert(i.next() == "a");
i.remove();
assert(abc[0] == "b"); // Failed assertion: 'abc[0] == "b"': is not true.

abc[0] is still "a" because remove doesn't remove the item from the actual collection. Instead, it gets removed from the internal copy inside the iterator.

To fix this problem a big refactoring is required so that remove actually removed the item from the original collection.

This is how kotlin solves this

KtList (and others) has no const factories

KtList (and others) has no const factories with const initializers. For example, KtList.of(1, 2, 3). And therefore no available pass constructed list with const to const constructors:

class State {
    final KtList<int> keys;
    const State(this.keys);
}
...

final state = const State(KtList.of(1, 2, 3, 4)); //no compile

compareBy{ }.thenBy{ }

I'm loving your project, but I had some issues like using groupBy and converting the following into kt.dart.

items.sortWith(compareBy<DictionaryItem> { it.gifPrio }.thenBy { it.gifSubPrio }.thenBy { it.gifTitle })

I didn't find anything in examples, readme or any documentation. I think you could add an exemple or add something in the sample, so other people can figure them out. I even thought for a second your library didn't have groupBy.

KtList.map/.mapIndexed & KtMutableList.map/.mapIndexed returns : [_$_ListItemType] != [ListItemType]

Is the following, suppose to return a _$_ with it? If so, how can I remove it when mapping a KtList?

KtList<String> object(String name, DateTime date); OR KtMutableList<String> object(String name, DateTime date);
print(list.fold((l) => null, (value) => value)
 .toList()
 .map(
 (listValue) => listValue.runtimeType)
 ));

I/Flutter: [_$_Object]

OR

KtList<String> object(String name, DateTime date); OR KtMutableList<String> object(String name, DateTime date);
print(list.fold((l) => null, (value) => value)
 .asList()
 .map(
 (listValue) => listValue.runtimeType)
 ));

I/Flutter: (_$_Object)

OR

KtList<String> object(String name, DateTime date); OR KtMutableList<String> object(String name, DateTime date);
print(list.fold((l) => null, (value) => value)
 .mapIndexed(
 (listValue) => listValue.runtimeType)
 ));

I/Flutter: [_$_Object]

from method fails when elements is null

It would be very helpful if the from factory constructor was changed to more gracefully handle when the 'elements' input parameter is null. I've found that many times my 'elements' input value is null when reading from databases. If I pass in a null value to the 'from' method, I get an exception. I would much rather have an EmptyList() returned.

I suggest the following mod:

  /**
   * Returns a new read-only list based on [elements].
   */
  factory KtList.from([Iterable<T> elements = const []]) {
    if (elements == null || elements.isEmpty) return EmptyList();
    return DartList(elements);
  }

Assigning an "emptyList()" to KtMutableList variable produces an error

Thanks for a great library! Using dart:collections after kotlin is painful, thanks god there's something to smooth it out :)

I just started to transition my code to this lib and wrote this:

  final KtMutableList<String> _digits = emptyList(); // also tried emptyList<String>()

It produces the following runtime error:

type 'EmptyList<dynamic>' is not a subtype of type 'KtMutableList<String>'

(or EmptyList<String> if I use an explicit version: emptyList<String>())

I'm not sure if this is a bug in a library or something I don't know about Dart's generics...
I checked and KtMutableList implements KtList so I don't see why this assignment should be a problem.

Subtracting lists of different types

Shouldn't all of these work?

class A {}

class B implements A {}

// Works fine...
listOf<A>(A()).minus(listOf<A>(B()));

// _TypeError (type 'A' is not a subtype of type 'B' of 'element')
listOf<A>(A()).minus(listOf<B>(B()));

// Not sure why but this one will throw as well.
listOf<A>(A()).minus(listOf<B>(B()).cast<A>());

// This one works, though.
// ignore: unnecessary_cast
listOf<A>(A()).minus(listOf<B>(B()).map((element) => element as A));

Relevant stack trace:

DartList.contains (...\kt_dart-1.0.0\lib\src\collection\impl\list.dart:0)
KtIterableExtensions.contains (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:336)
KtIterableExtensions.minus.<anonymous closure> (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:1031)
KtIterableExtensions.filterNotTo (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:536)
KtIterableExtensions.filterNot (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:511)
KtIterableExtensions.minus (...\kt_dart-1.0.0\lib\src\collection\kt_iterable.dart:1031)

The reason why I'm asking is actually Dart's type inference. Depending on how the type is inferred, seemingly similar code might or might not work.

Type inferred from the minus() signature - works fine:

listOf(A()).minus(listOf(B()));

Type inferred from the listOf() signature - won't work:

final listOfA = listOf(A());
final listOfB = listOf(B());
listOfA.minus(listOfB);

I tried to find what exactly is going on but honestly, I'm lost :). I can write a test if needed, though. I'm on Dart 2.18.2.

Implement operator []=

Thanks for bringing all those awesome kotlin extensions to Dart.

Just reporting the missing of the []= operator to the collections.

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.