-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
45 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ This repository is a collection of Dart code snippets and examples that may make | |
|
||
## How to Use | ||
|
||
To use this repository, simply clone or download the code and explore the examples. Each file is labeled with a short description of what it demonstrates. You can run the code using the Dart SDK, which can be downloaded from the [official Dart website](https://dart.dev/get-dart). | ||
To use this repository, simply clone or download the code and explore the examples. Every code is labeled with a short description of what it demonstrates. You can run the code using the Dart SDK, which can be downloaded from the [official Dart website](https://dart.dev/get-dart). | ||
|
||
It's important to note that some of these examples may not be suitable for production use, and should be used with caution. Additionally, some of the examples may have unintended consequences or may not behave as you expect, so be sure to read through the code and understand what it's doing before using it in your own projects. | ||
|
||
|
@@ -29,21 +29,22 @@ Please be sure to include a brief description of what your example demonstrates, | |
- [Using `await` without `async`](#using--without--) | ||
- [Mixing `var` and `final`](#mixing-var-and-final) | ||
- [Comparing doubles](#comparing-doubles) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
- [Recursive function with no base case](#reecursive-function-with-no-base-case) | ||
|
||
|
||
- [Using `as` with `null`](#using-as-with-null) | ||
- [Accessing private members](#accessing-private-members) | ||
- [Using `assert` with side effects](#using-assert-with-side-effects) | ||
- [Using `try` without `catch` or `finally`](#using-try-without-catch-or-finally) | ||
- [Method Chaining with the Cascade Operator](#method-chaining-with-the-cascade-operator) | ||
- [Operator Precedence and Grouping](#operator-precedence-and-grouping) | ||
- [Copying Maps with `Map.from()`](copying-maps-with--) | ||
- [String Concatenation without the + Operator](#string-concatenation-without-the-+-Operator) | ||
- [Surprising Results with `num.parse()`](<#surprising-results-with-num.parse()>) | ||
- [String Interpolation with Conditional Expressions](#string-interpolation-with-conditional-expressions) | ||
- [Behavior with Optional Variables](#behavior-with-optional-variables) | ||
|
||
# 💪🏻 Motivation | ||
|
||
> "Programming is not about what you know, it's about what you can figure out." | ||
> | ||
> | ||
> — _Chris Pine_ | ||
WTF-Dart is a repository created with the goal of showcasing surprising or unconventional behavior in Dart programming language. The repository contains a collection of Dart code snippets that demonstrate unexpected results or non-intuitive behavior in the language, which can be useful for developers who are learning Dart or working with it on a regular basis. | ||
|
@@ -55,6 +56,7 @@ Ultimately, WTF-Dart aims to help developers write more reliable and efficient c | |
> **⚠️ Note:** If you enjoy reading this document, please, [consider supporting the author of this collection](#-supporting). | ||
## Null is not null | ||
|
||
```dart | ||
var a = Null; | ||
if (a != null) { | ||
|
@@ -69,6 +71,7 @@ Ultimately, WTF-Dart aims to help developers write more reliable and efficient c | |
The reason for this behavior is that Null is actually a type in Dart, not a value. When you assign a variable the value Null, you're actually assigning it the null value of the variable's declared type (which is usually dynamic if you don't specify a type). So even though a is assigned the value Null, its type is still dynamic, and the condition a != null evaluates to true because a has a non-null value (even though that value happens to be null). This can be confusing if you're not familiar with Dart's type system and null safety. | ||
|
||
## This code does nothing | ||
|
||
```dart | ||
void main() { | ||
while(true); | ||
|
@@ -82,6 +85,7 @@ This code may seem like an infinite loop, but it actually does nothing because t | |
`Disclaimer:` The above code crashed my Dart Pad. | ||
|
||
## Switch case fall-through | ||
|
||
```dart | ||
void main() { | ||
var i = 2; | ||
|
@@ -104,6 +108,7 @@ void main() { | |
In Dart, switch cases can fall through to the next case unless a break statement is used. This code will print "Two or Three" because the case 2: statement falls through to case 3: | ||
|
||
## Recursive function with no base case | ||
|
||
```dart | ||
void main() { | ||
int factorial(int n) { | ||
|
@@ -119,6 +124,7 @@ void main() { | |
This code defines a recursive function to calculate the factorial of a number, but there is no base case to stop the recursion. When factorial(0) is called, the function will continue to call itself with negative numbers until a stack overflow error occurs. | ||
|
||
## Type Mismatch and Comparison Error | ||
|
||
```dart | ||
void main() { | ||
var x = 10; | ||
|
@@ -135,6 +141,7 @@ void main() { | |
At first glance, this code might seem reasonable: you're comparing two values to see which one is less. However, it will actually throw a runtime error because x is an integer and y is a string. In Dart, you cannot directly compare values of different types, so attempting to do so will result in a type error. This can be a WTF moment if you're not expecting it. | ||
|
||
## String indexing | ||
|
||
```dart | ||
void main() { | ||
var str = "Hello"; | ||
|
@@ -147,6 +154,7 @@ void main() { | |
In Dart, you can access individual characters of a string using square brackets, as if the string were an array. This can be a WTF moment if you're coming from a language that doesn't allow string indexing. | ||
|
||
## Using `is` with `!` | ||
|
||
```dart | ||
void main() { | ||
var a = "Hello"; | ||
|
@@ -161,6 +169,7 @@ void main() { | |
In Dart, you can use the `is` operator to check the type of a variable, and you can negate the result using `!`. This code will print "a is not an int" because `a` is a string. | ||
|
||
## Function with optional positional arguments | ||
|
||
```dart | ||
void main() { | ||
void greet(String name, [String greeting = "Hello"]) { | ||
|
@@ -177,6 +186,7 @@ void main() { | |
In Dart, you can define optional positional arguments by enclosing them in square brackets. This can be a WTF moment if you're not expecting optional arguments. | ||
|
||
## Using `await` without `async` | ||
|
||
```dart | ||
Future<String> getData() async { | ||
return "Data"; | ||
|
@@ -193,6 +203,7 @@ void main() { | |
In Dart, the await keyword is used to wait for a Future to complete, but it can only be used inside an async function. This code will produce a compiler error because main() is not declared as async. | ||
|
||
## Mixing `var` and `final` | ||
|
||
```dart | ||
void main() { | ||
final var a = "Hello"; | ||
|
@@ -205,6 +216,7 @@ void main() { | |
In Dart, `var` is used to declare a variable with inferred type, and final is used to declare a variable that can only be assigned once. This code will produce a compiler error because `var` and `final` cannot be used together. | ||
|
||
## Comparing doubles | ||
|
||
```dart | ||
void main() { | ||
var a = 0.1 + 0.2; | ||
|
@@ -222,6 +234,7 @@ void main() { | |
In Dart, comparing floating-point numbers can produce unexpected results due to the way they are represented in memory. This code will print "Not equal!" even though mathematically `0.1 + 0.2` is equal to `0.3`. | ||
|
||
## Using `as` with `null` | ||
|
||
```dart | ||
void main() { | ||
var a = null; | ||
|
@@ -234,9 +247,10 @@ void main() { | |
In Dart, you can use the `as` operator to cast a variable to a certain type, but it will throw a runtime error if the cast fails. This code will throw a `TypeError` because `a` is `null` and cannot be cast to `String`. | ||
|
||
## Accessing private members | ||
|
||
```dart | ||
class Person { | ||
String _name = "Alice"; | ||
String _name = "czar"; | ||
} | ||
void main() { | ||
|
@@ -247,9 +261,10 @@ void main() { | |
|
||
### 💡 Explanation: | ||
|
||
In Dart, you can use an underscore prefix to mark a member as private, but it is still accessible from outside the class. This code will print "Alice" even though `_name` is marked as private. | ||
In Dart, you can use an underscore prefix to mark a member as private, but it is still accessible from outside the class. This code will print "czar" even though `_name` is marked as private. | ||
|
||
## Using `assert` with side effects | ||
|
||
```dart | ||
void main() { | ||
var a = 0; | ||
|
@@ -263,6 +278,7 @@ void main() { | |
In Dart, you can use the `assert` keyword to check a condition during development, but it should not have any side effects. This code will print "1" even though `a` was modified by the` assert` statement. | ||
|
||
## Using `try` without `catch` or `finally` | ||
|
||
```dart | ||
void main() { | ||
try { | ||
|
@@ -276,6 +292,7 @@ void main() { | |
In Dart, you can use the `try` keyword to enclose code that may throw an exception, but you must also use either catch or finally to handle the exception. This code will produce a compiler error because try is not followed by catch or finally | ||
|
||
## Method Chaining with the Cascade Operator | ||
|
||
```dart | ||
class Person { | ||
String? name; | ||
|
@@ -285,17 +302,18 @@ class Person { | |
void main() { | ||
var person = Person() | ||
..name = "John" | ||
..age = 30 | ||
..name = "Czar" | ||
..age = 17 | ||
..greet(); | ||
} | ||
``` | ||
|
||
### 💡 Explanation: | ||
|
||
This will actually print "Hello, my name is John and I'm 30 years old.", because the cascade notation allows you to call the greet() method on the same object that you're setting the name and age properties on. This can be a bit confusing if you're not familiar with the cascade notation syntax. | ||
This will actually print "Hello, my name is Czar and I'm 17 years old.", because the cascade notation allows you to call the greet() method on the same object that you're setting the name and age properties on. This can be a bit confusing if you're not familiar with the cascade notation syntax. | ||
|
||
## Operator Precedence and Grouping | ||
|
||
```dart | ||
void main() { | ||
int x = 1; | ||
|
@@ -309,6 +327,7 @@ void main() { | |
In this code, the `||` and `&&` operators are used to combine multiple boolean expressions. However, the order of evaluation can be unexpected. In this case, the `&&` operator has higher precedence than the `||` operator, so `y > 0 && x < y` is evaluated first, resulting in `true`. Then, `true || true` is evaluated, resulting in `true`. This can be a WTF moment if you're not familiar with operator precedence in Dart. | ||
|
||
## Copying Maps with `Map.from()` | ||
|
||
```dart | ||
void main() { | ||
var source = {"a": 1, "b": 2}; | ||
|
@@ -324,6 +343,7 @@ void main() { | |
In this code, `Map.from()` is used to create a copy of a map `source`. However, when a value is updated in the copy, the original map is not affected. This can be a WTF moment if you're expecting the two maps to be linked together. | ||
|
||
## String Concatenation without the + Operator | ||
|
||
```dart | ||
void main() { | ||
String s = "hello" " world";// Output: hello world | ||
|
@@ -338,6 +358,7 @@ In Dart, you can concatenate strings using the `+` operator, just like in many o | |
In the above code, the string "hello" and "world" are placed next to each other without any operator between them. The resulting string is "hello world", which is printed to the console. This can be a WTF moment if you're not familiar with this syntax in Dart. | ||
|
||
## Surprising Results with `num.parse()` | ||
|
||
```dart | ||
void main() { | ||
String str1 = '42'; | ||
|
@@ -357,18 +378,21 @@ void main() { | |
This Dart code snippet demonstrates how to use the `num.parse()` method to convert strings to numbers. However, the results can be surprising due to the way Dart handles different types of numbers. In this case, the code parses three different strings as integers, doubles, and hexadecimal integers, respectively, producing unexpected output values for each. | ||
|
||
## String Interpolation with Conditional Expressions | ||
|
||
```dart | ||
void main() { | ||
bool isSunny = true; | ||
String message = 'It is ${isSunny ? 'sunny' : 'cloudy'} today.'; | ||
print(message); // Output: It is sunny today. | ||
} | ||
``` | ||
|
||
### 💡 Explanation: | ||
|
||
This Dart code snippet showcases the use of conditional expressions in string interpolation. It demonstrates how the result of a conditional expression can be directly included in a string using the "${expression ? trueCase : falseCase}" syntax. In this example, the value of the boolean variable `isSunny` determines whether the string "sunny" or "cloudy" is included in the resulting message. | ||
|
||
## Behavior with Optional Variables | ||
|
||
```dart | ||
void main() { | ||
String? message; | ||
|
@@ -380,12 +404,11 @@ void main() { | |
|
||
This Dart code snippet demonstrates the use of the null-aware operator with an optional variable. The null-aware operator "?." is used to call the `toUpperCase()` method on the `message` string variable, which is declared as nullable using the `String?` syntax. However, since the message variable is null, the output of the expression is also null, which may be unexpected to developers who are not familiar with the null-aware operator. | ||
|
||
|
||
# 🤝 Supporting | ||
|
||
| Service | Link | Action | | ||
| ---------------- | :------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | | ||
| **Patreon** | [Become a patron][patreon-url] | <a href="patreon.com/user?u=84015491"><img src="https://c5.patreon.com/external/logo/[email protected]" width="120px"></a> | | ||
| Service | Link | Action | | ||
| ----------- | :----------------------------: | :------------------------------------------------------------------------------------------------------------------------------------: | | ||
| **Patreon** | [Become a patron][patreon-url] | <a href="patreon.com/user?u=84015491"><img src="https://c5.patreon.com/external/logo/[email protected]" width="120px"></a> | | ||
|
||
## License | ||
|
||
|