質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

1回答

2886閲覧

The class doesn't have an unnamed constructor. エラーについて

mako_0221

総合スコア87

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2022/05/23 06:09

下記のコードを実行しようとすると以下のようなエラーが//here1で出力されます、
The class 'TopPage' doesn't have an unnamed constructor. (view docs) Try using one of the named constructors defined in 'TopPage'.

Dart

1import 'package:flutter/material.dart'; 2import 'dart:math'; 3 4void main() => runApp(TopPage()); //here1 5 6class TopPage extends StatelessWidget { 7 List<Widget> _tiles; 8 _tiles.add(UniqueColorGenerator.getColor());// here2 9 _tiles.add(UniqueColorGenerator.getColor());;// here2 10 11 Widget build(BuildContext context) { 12 return Container( 13//omit 14 } 15} 16 17class UniqueColorGenerator { 18 static List _colorOptions = [ 19 const Color(0xff2196f3), 20 const Color(0xfff44336), 21 ]; 22 static Random _random = Random(); 23 static Color getColor() { 24 final selectedColor = _colorOptions.removeAt(_random.nextInt(_colorOptions.length)); 25 print(selectedColor); 26 return selectedColor; 27 } 28}

そこで、上記の"here2"について、以下のように直接List<Widget> _tilesを初期化してあげるとエラーは出力されなくなります。

Dart

1class TopPage extends StatelessWidget { 2// final Color _color = UniqueColorGenerator.getColor(); 3 List<Widget> _tiles=[ 4 UniqueColorGenerator.getColor(), 5 UniqueColorGenerator.getColor() 6 ]; 7 8 Widget build(BuildContext context) { 9 return Container( 10 color: _color, 11 child: const Padding(padding: EdgeInsets.all(100.0))); 12 } 13}

diagnostic-messagesを参照すると、

Description
The analyzer produces this diagnostic when an unnamed constructor is invoked on a class that > defines named constructors but the class doesn’t have an unnamed constructor.

名前なしコンストラクタを呼び出そうとしているが、名前なしコンストラクタがないですよ、というメッセージに読み取れます。

オブジェクト指向およびクラスを勉強を初めたばかりで、Language Tourのコンストラクタ部分を読んでも、このエラーの意味・問題点、解決方法がわからないのですが、(基本的なコンストラクタの考え方がわかっておらず申し訳ございませんが)、アドバイス願えますでしょうか?

よろしくお願い申し上げます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

TopPageクラスの定義がエラー状態のため、構文解釈処理の内部的なもろもろの情報が不足し、その結果そのクラスを利用しているところで、人が理解できないエラーメッセージが出たということじゃないでしょうか。
here1のところで出たエラーがなぜこのようなメッセージになったのかについてしらべることは、今回のケースでは無意味です。

これに関してはhere1の利用側のエラーはとりあえず無視し、クラス定義をエラーなしの状態にするというのが実装時のセオリーだと思います。

投稿2022/05/23 08:32

ta.fu

総合スコア1667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mako_0221

2022/05/23 14:35

コメントありがとうございます。下記のコードで意図通り実行することができました。※コメント欄のためコードブロックでなく申し訳ございません。 import 'package:flutter/material.dart'; import 'dart:math'; void main() => runApp(TopPage()); class TopPage extends StatelessWidget { final List<Widget>? _tiles=[]; @override Widget build(BuildContext context) { _tiles!.add(Container(color:UniqueColorGenerator.getColor(),child: Padding(padding: EdgeInsets.all(100.0)))); _tiles!.add(Container(color:UniqueColorGenerator.getColor(),child: Padding(padding: EdgeInsets.all(100.0)))); print( _tiles); return MaterialApp( home:Scaffold( appBar:AppBar( title:Text("TESTING"), ), body:Row( children: _tiles!, ), ) ); } } class UniqueColorGenerator { static List _colorOptions = [ const Color(0xff2196f3), const Color(0xfff44336), ]; static Random _random = Random(); static Color getColor() { final selectedColor = _colorOptions.removeAt(_random.nextInt(_colorOptions.length)); print(selectedColor); return selectedColor; } }
mako_0221

2022/05/23 14:47

ポイントは3点ございました。 ①final List<Widget>? _tiles=[];について "=[]"で初期化する必要がある。Listであることの宣言だけではなく、[]からのリストであることを示し初期化する必要がある?のですね。 ②_tiles!.add(Cont..... 宣言時に?を使用しているので利用時に!を追加しました。 ③Widget build(BuildContext context) {}のBody内に、_tiles!.add()を記述する。 正直3番は何故なのか理解することができませんでした。The name of a constructor must match the name of the enclosing class.のエラーに対して修正したのですが、なぜbuild()メソッド内でしか、初期化したListに対する要素の追加が許容されないのでしょうか? build()メソッドはStatelessWidgetから承継していると言ったところに原因があるのでしょうか?super()を使って継承元に_tiles.add()で要素追加などを伝える必要があるのかと、試行錯誤したのですが、この点だけ解決に至らず、もしよければアドバイス願えますでしょうか? 重ねて申し訳ございませんが、よろしくお願い申し上げます。
ta.fu

2022/05/23 23:31

The name of a constructor must match the name of the enclosing class. _tiles.add(); 上の書き方が`Named constructors`の書き方にマッチしていたので、構文解釈がそれだと認識して処理したのでしょう。 _tilesはクラス名と違うので上のエラーが出たと思います。 ①②についても理解していないんじゃないかというのが見受けられます。 ① final句が付いた変数は=で初期化する必要があり、またそこ以外での代入はできません。 書き方の例外として、メンバーの場合にはコンストラクタでの初期化での代入が許されています。 また今回のケースだとメンバーでクラス内で情報が確定するわけなので、?を付けてnull許容にする必要は全くないと思います。 ② ①にも書きかましたが今回のメンバーはnull許容にする必要がないので、宣言部分の?を外すのが妥当だと思います。
mako_0221

2022/05/24 07:19

コメントありがとうございます。 ③に関しては「_tilesはクラス名と違うので上のエラーが出たと思います。」がわからず、ずっと考えて調べていました。 https://stackoverflow.com/questions/61759492/flutter-dart-how-to-sort-list-by-key 等の記事を読んでみてふと思ったのですが、そもそもクラスの定義において、コンストラクタでもない、メソッドでもないのに、急に何かの処理「_tiles.add()」を実行することが自分でやっていて意味が分からないことだと思えてきました・・・ ということで、以下のようにコンストラクタとして実行できることを触りながら確認することができませんでした。 var _tiles = <Widget>[]; TopPage(){ _tiles.add( Container( color: UniqueColorGenerator.getColor(), child: Padding(padding: EdgeInsets.all(100.0))) ); _tiles.add( Container( color: UniqueColorGenerator.getColor(), child: Padding(padding: EdgeInsets.all(100.0))) ); } ただ、もちろんこのようにコンストラクトとして実行して、_tilesを初期化することに意味はないように思えるので物の理解として記載いたしました。 ②についてはおっしゃる通り、理解不足でした。まだ学びの段階で何となく?をつければ動くなどという感覚でやっていますが、少しずつnullを許容すべきなのかそうではない文脈なのかでしっかり使い分けていきたいと思います。 ①final句の初期化については、=で初期化しなくても、以下のようにできたりできなかったり、もう少し調べて勉強してみます。 ↓ class User { final String name; User(this.name); } ↓これはNG class User { final String name; User(name){ this.name = name } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問