トップページ⇒tech
989コメント254KB

D言語 Part22

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2009/06/22(月) 01:38:41
プログラミング言語 D (D Programming Language) について語るスレッドです。
過去スレ、関連スレは >>2

■前スレ
http://pc12.2ch.net/test/read.cgi/tech/1234363551/

■本家
ttp://www.digitalmars.com/d/
ttp://www.kmonos.net/alang/d/ (和訳)

■コンパイラ
http://www.digitalmars.com/d/dcompiler.html (DMD, 本家)
http://dgcc.sourceforge.net/ (GDC, gccフロントエンド)
http://www.dsource.org/projects/ldc (LDC, バックエンドにLLVM)

■参考URL
ttp://f17.aaa.livedoor.jp/~labamba/ (D言語研究)
ttp://f17.aaa.livedoor.jp/~labamba/?D%B8%C0%B8%ECBOF (D言語BOF)
ttp://dsource.org/ (dsource)
ttp://tinyurl.com/candcpp2d (C/C++に疲れた人のD言語)
ttp://www.kmonos.net/alang/wnd/ (わかったつもりになるD言語)
ttp://shinh.skr.jp/d/ (SDL, SDL_*, OpenGL, GLU, glutのポーティングとか)
ttp://shoo.s20.xrea.com/shoo/programing (D言語とTangoの入門講座)
ttp://www.nicovideo.jp/mylist/4453698 (D言語で作られた芝ゲー niconico動画)
ttp://www.asahi-net.or.jp/~cs8k-cyu/ (ABA Games)

■ IDE
ttp://dronten.googlepages.com/dscite (DSciTE)
ttp://forums.codeblocks.org/index.php?board=20.0 (Code::Blocks)
ttp://www.dprogramming.com/entice.php (Entice Designer)
ttp://www.dsource.org/projects/descent (Descent)
ttp://www.dsource.org/projects/poseidon (Poseidon)
0696デフォルトの名無しさん2009/08/23(日) 23:14:39
白魔術はないのか
0697デフォルトの名無しさん2009/08/23(日) 23:44:49
digitalmars.com での "black magic" の検索結果 約 176 件
0698デフォルトの名無しさん2009/08/24(月) 01:00:33
>>683 それだけではなんとも
0699デフォルトの名無しさん2009/08/24(月) 03:09:30
あ,なんだ答え出てたのか失礼
0700デフォルトの名無しさん2009/08/24(月) 07:56:53
>>693 そうなっているとどうしてわかりにくいの?
どこまでがモジュール名なのかわからないからとか?
ファイル名出ててわかりにくいのはなぜ?
0701デフォルトの名無しさん2009/08/24(月) 08:03:07
>>695
ふと思い出してvoodooを調べてみたら
http://ja.wikipedia.org/wiki/%E3%83%96%E3%83%BC%E3%83%89%E3%82%A5%E3%83%BC%E6%95%99
に、ブラックマジックという単語が出てるぞ。語源かは知らんが。
0702デフォルトの名無しさん2009/08/24(月) 10:28:15
>>700
例えばstd.functional.dのbinaryFunImplでエラーが発生したとメッセージが出るとします。
でも、自分が書いたコードの中で直接binaryFunImplを使ってないし、そもそもstd.functionalをimportすらしていません。
正解はstd.algorithmの中の関数の中でbinaryFunが呼ばれてるからなんですが、
自分が書いたコードのどこが間違っているのか、特定に手間がかかります。
0703デフォルトの名無しさん2009/08/24(月) 11:28:48
ライブラリを作る段階でこんな感じにすればいいのではないかと。
import std.stdio;
void func2(T, string f=__FILE__, int l=__LINE__)(T a){writeln("func2: ", f, "(", l, "): ", a);}
void func(T, string f=__FILE__, int l=__LINE__)(T a){func2!(T,f,l)(a);}
void main(){func(10);}
0704デフォルトの名無しさん2009/08/24(月) 12:18:25
テンプレート展開の「スタックトレース」的な機能は必須だよな
0705デフォルトの名無しさん2009/08/24(月) 12:55:06
template instanciationに失敗したら呼び出し元の関数とかを全部エラー出してくれるだけでもいいやな
0706デフォルトの名無しさん2009/08/24(月) 18:21:11
しかし今月の更新は遅いな…どんな破壊的変更が待っているのか…
今からなんだかワクワクしてきた…ッ!
0707デフォルトの名無しさん2009/08/24(月) 19:11:12
string型の文字列をubyteの配列に変換したいんだが…
どうすれば?
0708デフォルトの名無しさん2009/08/24(月) 19:16:29
>>707 何のために?
0709デフォルトの名無しさん2009/08/24(月) 19:19:02
>>708
暗号化
0710デフォルトの名無しさん2009/08/24(月) 19:20:11
ならcast(ubyte[])とかでよくね?
0711デフォルトの名無しさん2009/08/24(月) 19:21:02
ふ〜む
やってみる
0712デフォルトの名無しさん2009/08/24(月) 19:22:46
immutable(ubyte)[]にしないと
0713デフォルトの名無しさん2009/08/24(月) 19:25:06
>>712
了解
0714デフォルトの名無しさん2009/08/24(月) 19:27:14
可能なら const(void)[] などを使うのもよい。
0715デフォルトの名無しさん2009/08/24(月) 21:02:37
>>703
なるほど、実行時エラーはそれでいけますね。
しかし、全ての関数にそれを仕込むのは手間がかかりそうです。
またPhobosをよく使うので、そこはどうしようもないのがつらいところ。
>>704-705
コンパイル時のエラーメッセージで困るのは、確かにテンプレート絡みですね。
今後に期待?
0716デフォルトの名無しさん2009/08/24(月) 22:05:22
いつになったら関数がタプル返せるようになるんだよおい
0717デフォルトの名無しさん2009/08/24(月) 23:11:55
あ…あしたさ…
0718デフォルトの名無しさん2009/08/24(月) 23:47:35
俺にはdmdを改造して特定の機能をなかったことにする程度の能力しかない!
0719デフォルトの名無しさん2009/08/24(月) 23:49:46
タプル返す関数があって何がうれしいの?
構造体でいいじゃんと思うのだけど…
0720デフォルトの名無しさん2009/08/24(月) 23:52:27
毎回作るのめんどいじゃんってのがタプルの起源だったきがする、
無名delegateも似たような理由だし。
0721デフォルトの名無しさん2009/08/24(月) 23:56:41
複数の戻り値を返すとか?
outな引数使えばいいと思う
0722デフォルトの名無しさん2009/08/24(月) 23:57:32
>>719
Tuple!(int, int) f(int, int) { /**/ }

f(f(2, 3))
0723デフォルトの名無しさん2009/08/24(月) 23:58:03
>>721
outは型推論ができないから糞すぎる。
0724デフォルトの名無しさん2009/08/24(月) 23:59:11
引数にタプル取る関数があって何がうれしいの?
構造体でいいじゃんと思うのだけど…
0725デフォルトの名無しさん2009/08/25(火) 00:13:30
あれ?いつからenumの型名必須になったんだっけ?
これ全部直すのめんどくせーw
0726デフォルトの名無しさん2009/08/25(火) 00:19:50
必須ではないよ。今でも無名構造体は存在する
0727デフォルトの名無しさん2009/08/25(火) 00:44:00
newで作る配列の中身を初期化しない = void的な指定の仕方が思い出せない

>>725
D2ならわりと初期のころから
引数の型が特定のenumなら、その型に当たる部分は型名省略してもいいだろうと以前から話題には上るし、
07のウォルたんの公演でもやりたいと言っていたが、流れ続けて現在に至る
0728デフォルトの名無しさん2009/08/25(火) 00:44:59
out引数は
extern(C) void hoge(int *n);
を
extern(C) void hoge(out int n);
と書くためにある
0729デフォルトの名無しさん2009/08/25(火) 01:20:34
DFL更新されました
dmd2.031対応
0730デフォルトの名無しさん2009/08/25(火) 10:33:28
おお!
0731デフォルトの名無しさん2009/08/25(火) 10:39:25
見当たらないんだが?
0732デフォルトの名無しさん2009/08/25(火) 11:45:47
つ trunk
0733デフォルトの名無しさん2009/08/25(火) 14:49:04
あった
0734デフォルトの名無しさん2009/08/25(火) 16:22:47
下記のソースはなぜ文字列を出力しないのだろう?
int main()
{
ubyte[] ary;

ubyte[] pico( ubyte[] sage ) { return sage = cast(ubyte[])"sage"; }
void fuga( ubyte[] sage ) { sage = pico( sage ); }

ary.length = 4;
fuga( ary );
writefln( "output: %s", cast(string)ary );

// 入力待ち
readln();

return 0;
}
/* 実行結果
* output:
*/
0735デフォルトの名無しさん2009/08/25(火) 16:24:56
動かしてないけど、たぶん inout がないからだと思う
07367352009/08/25(火) 16:27:23
fuga関数の引数部分ね
0737デフォルトの名無しさん2009/08/25(火) 16:27:54
>>735
fuga関数にinoutを追加したら動きました!
今日一日悩んでたので感謝^^
0738デフォルトの名無しさん2009/08/25(火) 16:31:29
なんでそんなきもいことしてんの?
0739デフォルトの名無しさん2009/08/25(火) 16:37:42
>>738
いや〜、セーブデータを作るモジュールを作っていて詰まったのですよ(;^^
0740デフォルトの名無しさん2009/08/25(火) 16:51:21
andrei曰くDでは void main() {} 推奨とのこと
0741デフォルトの名無しさん2009/08/25(火) 16:53:30
すこしはconst-correctness意識すべき
0742デフォルトの名無しさん2009/08/25(火) 16:56:46
待て
inoutじゃなくてrefだ
0743デフォルトの名無しさん2009/08/25(火) 16:57:58
>> 740
そうなんですか? 知りませんでしたorz

>> 742
ぇ..
0744デフォルトの名無しさん2009/08/25(火) 17:00:33
inoutは古い仕様なのでrefにして
あと >> とレス番は離さないで
0745デフォルトの名無しさん2009/08/25(火) 17:01:28
>>744
すみません・・
焦っていたもので(;^^

resに変えておきます。
07467452009/08/25(火) 17:02:23
また間違えた。。
refですね(;--
0747デフォルトの名無しさん2009/08/25(火) 17:05:18
関数の引数はデフォルトで in に・・・
ウォルたんなら・・・ウォルたんなら・・・やってくれる(はず)
0748デフォルトの名無しさん2009/08/25(火) 17:26:09
>>747
あほかw
そんなことしたらinじゃない普通の引数を表すキーワードが必要になるだろうが。
0749デフォルトの名無しさん2009/08/25(火) 19:00:31
普通のはなくすってことだよ
0750デフォルトの名無しさん2009/08/25(火) 19:53:43
>>749
その方がいいかも知れんね。それこそ >>734 みたいな直観的じゃないことがたまにあるし。
void hige( ubyte[] fuke ) { fuke.length = fuke.length + 64; }
こういうのとか。
0751デフォルトの名無しさん2009/08/25(火) 20:49:04
確かによく考えたら無意味だよなあ
まあswitchがそのまんま残ってるくらいだから無くならないだろうけど
0752デフォルトの名無しさん2009/08/25(火) 22:15:40
同じ関数名、同じ型の引数で返り値の型のみ違う関数って作れますか?
0753デフォルトの名無しさん2009/08/25(火) 22:26:12
出来ないはず
たとえばコンパイラが返り値の受け手がいない関数の処理をどうしたらいいか考えてみると分かりやすい
0754デフォルトの名無しさん2009/08/25(火) 22:27:40
>>752
テンプレート関数でいいなら。
T func(T)(){
static if (is(T==int)){return 0;}else{return 1.0;}
}
0755デフォルトの名無しさん2009/08/25(火) 23:24:56
interfaceだけ実行時型情報がとれないとかどうなってるんだ
少なくとも、この挙動が正しいならプロパティ名を分けないと分からん

interface I {}
class C : I {}
class D : C {}

void o(in Object obj) { writeln(obj.classinfo.name); }
void i(in I obj) { writeln(obj.classinfo.name); }
void c(in C obj) { writeln(obj.classinfo.name); }

void main() {
auto d = new D;
o(d); // classname D
i(d); // classname I
c(d); // classname D
}
0756デフォルトの名無しさん2009/08/25(火) 23:30:34
>>755 それはバグっぽいなあ
0757デフォルトの名無しさん2009/08/26(水) 00:06:40
関数の引数にしたが、とりあえずインターフェースの参照ならなんでもこうなるようだ
とりあえずリポートしておいた
0758デフォルトの名無しさん2009/08/26(水) 00:08:24
void i(in I obj) {writeln((cast(Object)obj).classinfo.name); }
たぶんIUnknownとかCOMなんかの関係があってObjectにcastできないと実行時型情報が取り出せないんじゃないかと予想
0759デフォルトの名無しさん2009/08/26(水) 00:09:46
標準ライブラリでもたまに
template Te(T) if (is (T : Object)) { ... }
とか見かける
interfaceはいらない子ですか?
0760デフォルトの名無しさん2009/08/26(水) 07:40:00
正しそうなのにどうしてダメなんでしょうか
import std.stdio;
interface I {
 void a() const;
}
class C : I {
 override void a(){} const
}
void main()
{
 void i(in I obj) {
  writeln((cast(Object)obj).classinfo.name);
  obj.a();
 }
 void c(in C obj) {
  writeln(obj.classinfo.name);
  obj.a();
 }
 i(new C);
 c(new C);
}
main.d(6): Error: function main.C.a of type void() overrides but is not covariant with main.I.a of type const void()
main.d(6): Error: function main.C.a does not override any function
0761デフォルトの名無しさん2009/08/26(水) 08:08:33
あ ごめん const の場所だね
0762デフォルトの名無しさん2009/08/26(水) 08:38:13
引数が全部inだとクラスのconst関数しか呼び出せなくて困るからダメなんだな
0763デフォルトの名無しさん2009/08/26(水) 09:01:51
void a(in C c)
{
}
0764デフォルトの名無しさん2009/08/26(水) 09:02:54
ごめミス
0765デフォルトの名無しさん2009/08/26(水) 22:34:38
inが普通の変数宣言のときもconst scopeで有効になったらタイプ数減っていいなあ
0766デフォルトの名無しさん2009/08/26(水) 22:40:21
オー、ノー!
俺が一番嫌いな言葉はsynchronizedで二番目がimmutableなんだぜー!
0767デフォルトの名無しさん2009/08/26(水) 23:38:57
ジョセフ乙
0768デフォルトの名無しさん2009/08/27(木) 01:37:27
inとか見て思ったんだけどいつかは既存の string toString() が
const string toString() に大変身するの?
0769デフォルトの名無しさん2009/08/27(木) 02:00:12
やったことがなかったがC++と同様にconst メンバと非constメンバをオーバーロードできる
また >>762 のことにより非const関数も別に必要なので
string toString(); と const string toString(); の両方になるべきだと思う
0770デフォルトの名無しさん2009/08/27(木) 02:04:32
toStringでインスタンスの中身書き換えられたり、constと非constで挙動が違うってのも困るから、
const string toString() がいいとおもう。
>>762 に関しては ref 使えばいいのでは?
0771デフォルトの名無しさん2009/08/27(木) 02:06:55
元々参照なのにいちいちref付けるのもどうかと思ったけど
書いてみたらさほど手間でもないかな?
0772デフォルトの名無しさん2009/08/27(木) 02:08:54
stack overflowになるんですけど・・・
import std.stdio;
class A {
 override string toString() {
  return "A";
 }
 override string toString() const
 {
  return "const(A)";
 }
}
void main() {
 auto a = new A;
 writeln(a.toString());
 const ca = new A;
 writeln(ca.toString());
}
0773デフォルトの名無しさん2009/08/27(木) 02:10:25
あれ?じゃなくてobject.Error: Access Violationか
なんでだ
0774デフォルトの名無しさん2009/08/27(木) 02:27:24
>>771 immutable string toString()はどうする
0775デフォルトの名無しさん2009/08/27(木) 02:28:08
間違った >>774 は >>770 へ
07767702009/08/27(木) 03:04:33
>>774
個人的には、少なくともObjectクラスのメンバ関数としてはいらないと思うなぁ
そもそもimmutableメンバ関数ってどういう時に使うと便利なものなの?
0777デフォルトの名無しさん2009/08/27(木) 04:38:19
>>776
static関数だとimmutableにしたりすることはある。なんらかのIDつけるときとか。
インスタンスでそういうケースもないことはないかなという気はする。
0778デフォルトの名無しさん2009/08/27(木) 07:18:53
>>772
コンパイルできちゃう所に痺れる
07797702009/08/27(木) 12:09:38
>>777
一応、mutableなインスタンスでは実行できず、imutableなインスタンスなら実行可能なメンバ関数というものではあるらしい。
auto a = new A;
immutable b = cast(immutable)a;
a.immutableMemberFunction(); //NG
b.immutableMemberFunction(); //OK
つまり、immutableメンバ関数外からは絶対にメンバ変数が変更されないという保証がなされる。
ということは、関数内部でメンバに対してmutexロックなど排他制御をする必要がなくなる…という意味では価値があるかもしれない。
けど、だとしたら逆にいえば普通のメンバ関数とかconstメンバ関数内では、メンバ変数にアクセスする際には
必ず排他制御を行わなきゃいけないということになる。
だけどそれは、パフォーマンス的にあまり現実的とはいえず、普通はやらないので、
やっぱりimmutableメンバ関数の有用性には疑問が残る。
0780pmlynzZPUThDtKP2009/08/27(木) 12:19:46
<a href="http://artemis2.wackwall.com/post/postId/12925/">greek gods artemis</a>
<a href="http://artemis2.wackwall.com/post/postId/12927/">pictures of artemis</a>
<a href="http://artemis2.wackwall.com/post/postId/12929/">email artemis cosmetics mumbai</a>
<a href="http://artemis2.wackwall.com/post/postId/12930/">artemis goddess of the hunt</a>
<a href="http://artemis2.wackwall.com/post/postId/12931/">artemis and the stag</a>
<a href="http://artemis2.wackwall.com/post/postId/12934/">artemis nightshade</a>
<a href="http://artemis2.wackwall.com/post/postId/12936/">artemis dog food</a>
<a href="http://artemis2.wackwall.com/post/postId/12938/">artemis the goddess of hunt</a>
<a href="http://artemis2.wackwall.com/post/postId/12940/">remove generic artemis</a>
<a href="http://artemis2.wackwall.com/post/postId/12942/">symbol of artemis</a>
<a href="http://artemis2.wackwall.com/post/postId/12943/">artemis myth</a>
<a href="http://artemis2.wackwall.com/post/postId/12945/">artemis - greek mythology</a>
<a href="http://artemis2.wackwall.com/post/postId/12947/">artemis cat food</a>
<a href="http://artemis2.wackwall.com/post/postId/12948/">artemis orthia</a>
<a href="http://artemis2.wackwall.com/post/postId/12950/">artemis symbol</a>
<a href="http://artemis2.wackwall.com/post/postId/12952/">tragic love story artemis</a>
0781デフォルトの名無しさん2009/08/27(木) 12:40:45
castせずこうしてね
auto a = new immutable(A);
07827702009/08/27(木) 15:32:30
>>781
import std.stdio;
import std.contracts;
class A {
    int i = 0;
    immutable void immutableMemberFunction() { writeln("immutableMemberFunction, i=", i); }
}
void main() {
    auto a = new A;
    a.i = 100;
    immutable b = cast(immutable)a;
    a = null;
    b.immutableMemberFunction();
}
こういう場合があるため、それは不適当と判断しました。
07837702009/08/27(木) 15:41:53
assumeUniqueを使おうとして import std.contracts; したはいいけど配列しか対応していない
ことに絶望したのは言うまでもない。
………なぜだ…。
0784デフォルトの名無しさん2009/08/27(木) 16:16:35
>>782
キャストしたらimmutable性を自分で保証しなければならず
なくなったり書き換えられたりしたら未定義動作なのですが
これはそのケースになりませんか?
ttp://www.kmonos.net/alang/d/2.0/const3.html
> しかし、だからといって、データを書き換えられるようになるわけではありません:
>*q = 3; // コンパイルは通るが、未定義動作

それはともかくこうするとキャストいらないですよ
import std.stdio;
import std.contracts;
class A {
 int i = 0;
 immutable void immutableMemberFunction() { writeln("immutableMemberFunction, i=", i); }
 this(){}
 this(A other) {
  i = other.i;
 }
}
void main() {
 auto a = new A;
 a.i = 100;
 auto b = new immutable(A)(a);
 b.immutableMemberFunction();
}
07857702009/08/27(木) 16:57:19
>>782
値を変更した後にimmutableにキャストし、a = null;でimmutable性を保証しているため、
その未定義動作には当てはまらないと思いますが…(assumeUniqueの仕様例と実装を見る限り)
そのコードはいいかも、と思ったけど、以下のように継承に対応することができないのでは?
import std.stdio;
class A {
    int i = 0;
    immutable void immutableMemberFunction() { writeln("A: i=", i); }
    this(){}
    this(A other) { i = other.i; }
}
class B: A {
    int j = 0;
    this(){}
    override immutable void immutableMemberFunction() { writeln("B: i=", i, ", j=", j); }
}
void main() {
    auto a = new B;
    a.i = 1; a.j = 2;
    immutable A b = cast(immutable)a;
    immutable A c = new immutable(A)(a);
    a = null;
    b.immutableMemberFunction();
    c.immutableMemberFunction();
}
0786デフォルトの名無しさん2009/08/27(木) 17:12:20
>値を変更した後にimmutableにキャストし、a = null;でimmutable性を保証しているため、
あーなるほど確かに
下のコードはぱっと見ではわからないので後で見ます
0787デフォルトの名無しさん2009/08/27(木) 17:16:28
非immutableメンバ関数内で排他制御をしなきゃならん、じゃなくて、
メンバ関数を呼び出す側が排他制御をする必要があるかどうか判断できる、
ということのような気がする。
0788デフォルトの名無しさん2009/08/27(木) 17:50:48
読みました
immutable A b = cast(immutable)a;//これはcast(immutable(B))aです
immutable A c = new immutable(A)(a);//こっちはスライスされます
こうしましょう
immutable A c = new immutable(B)(a);
0789デフォルトの名無しさん2009/08/27(木) 18:24:47
>>787
確かにその通りですね。ただ、それはimmutableなインスタンスの有用性であって、
immutableメンバ関数の有用性ではない気がするのですが…
(immutableなインスタンスであれば排他制御なしにconstメンバ関数も呼び出すことができる。
ではimmutableメンバ関数が有用なのはどんな時?)

>>788
もはや自分が何を言いたかったのか忘れてきたけど、何かそれは元も子もない何かを感じる
immutableなインスタンスを作る時にいつもそれができるとは限らないし…
07907882009/08/27(木) 18:36:31
>>789
僕はキャストを使わなくてすむ方法があるのだから
そっちの方がいいなーということくらいしかないですw
0791デフォルトの名無しさん2009/08/27(木) 18:55:24
>>789
> (immutableなインスタンスであれば排他制御なしにconstメンバ関数も呼び出すことができる。
> ではimmutableメンバ関数が有用なのはどんな時?)
>782のような場合にimmutableにキャストし忘れた場合にはエラーになるけれど、
関数をimmutableと修飾しておかない場合、エラーにできなくなるような気がする。
07927702009/08/27(木) 19:23:21
>>791
もう値が変更されなくなった後でないと使うことが許されないメンバ関数…ってことか?
終了処理後でなければ実行することができないと明示するための宣言として利用できるということかな?
Hash計算クラスの、終了処理後でないと計算結果が出せない…みたいな。
0793デフォルトの名無しさん2009/08/27(木) 19:58:10
immutableがゲシュタルト崩壊してきた
0794デフォルトの名無しさん2009/08/27(木) 20:43:45
なんでimmutableなんてものを作った
0795デフォルトの名無しさん2009/08/28(金) 00:32:57
マルチスレッドで他の言語を圧倒しようという目論見
■ このスレッドは過去ログ倉庫に格納されています